Prevent variable from breaking out of Function scope

Welcome Forums General PowerShell Q&A Prevent variable from breaking out of Function scope

This topic contains 3 replies, has 2 voices, and was last updated by

 
Participant
1 year, 11 months ago.

  • Author
    Posts
  • #59380

    Participant
    Points: 0
    Rank: Member

    Hi
    I'm now to this forum (:

    I encountered the following behavior:
    If you pass a variable to a function and change it inside it, it will not change the variable at the parent scope as expected (without overriding the scope with $global: or something like this).
    But if you do the same with complex objects the function will override the variable on the parent scope unexpectedly.

    1. Why is that happening?
    2. How to prevent it?

    Example

    $VarOut = @{'A' = 'Out'}
    'Start: ' + $VarOut['A'] #Will output 'Out'
    
    function Get-Something
    {
        [CmdletBinding()]
        param
        (
            $VarIn
        )
        $VarIn['A'] = 'In'
        'In function: ' + $VarIn['A'] #Will output 'In'
    }
    Get-Something -VarIn $VarOut
    
    'End: ' + $VarOut['A'] #Will output 'In' and not 'Out'
    

    Thank you

  • #59386

    Participant
    Points: 2
    Rank: Member

    I think the problem you're having is due to the type of value you're passing in to the function, which is a hashtable. This is a reference type, so when you re-assign the value of the 'A' key, then it does it by reference to the original which is saved as variable $VarOut. There's a decent explanation of the difference in reference and value types here:

    Value types vs Reference types


    You can see the difference if you change your script to only pass string values:

    $VarOut = 'Out'
    'Start: ' + $VarOut #Will output 'Out'
    
    function Get-Something
    {
        [CmdletBinding()]
        param
        (
            $VarIn
        )
        $VarIn= 'In'
        'In function: ' + $VarIn #Will output 'In'
    }
    Get-Something -VarIn $VarOut
    
    'End: ' + $VarOut #Will output 'Out'
    
    • #59392

      Participant
      Points: 0
      Rank: Member

      Thank you
      "Reference types" this was the term I was looking for

  • #59388

    Participant
    Points: 0
    Rank: Member

    Hi

    I fund the the solution, I just needed to clone it before editing

    $VarOut = 'Out'
    'Start: ' + $VarOut #Will output 'Out'
    
    function Get-Something
    {
        [CmdletBinding()]
        param
        (
            $VarIn
        )
        $VarIn = $VarIn.Clone() #Fix
        $VarIn= 'In'
        'In function: ' + $VarIn #Will output 'In'
    }
    Get-Something -VarIn $VarOut
    
    'End: ' + $VarOut #Will output 'Out'
    

The topic ‘Prevent variable from breaking out of Function scope’ is closed to new replies.