Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing variables created inside a function after the function has executed

I'm using a function which creates some variables I'd like to use after the function has processed. I've tried accessing them directly but I can't. How would I go about doing this?

like image 203
Sune Avatar asked Dec 01 '22 07:12

Sune


2 Answers

Variables inside functions don't survive after the function has been run. If you want to access them after the function has processed, prefix them with a scope modifier.

PS> function test-var{ $script:var='foo' }
PS> test-var # excute the function
PS> $var #print var
foo

Type this in your console for more information:

PS> Get-Help about_Scopes
like image 106
Shay Levy Avatar answered Dec 06 '22 08:12

Shay Levy


as Shay pointed out you can create what are called global variables inside the function scope that will be available at higher level scopes. However global variables are generally not a good idea and I'd like to suggest some alternatives for you.

This is from the wikipedia global variable page:

They are usually considered bad practice precisely because of their non-locality: a global variable can potentially be modified from anywhere (unless they reside in protected memory or are otherwise rendered read-only), and any part of the program may depend on it.[1] A global variable therefore has an unlimited potential for creating mutual dependencies, and adding mutual dependencies increases complexity.

Some alternatives:

  • Make the function return data needed by the caller. Powershell functions should generally return the data related to the noun in the Powershell function naming convention of Verb-Noun. If you need to return other data not associated to the noun consider making a second function.

    function Get-Directories {
        param ([string] $Path)
    
        # Code to get or create objects here.
        $dirs = Get-ChildItem -Path $Path | where {$_.PsIsContainer}
    
        # Explicitly return data to the caller.
        return $dirs
    }
    
    $myDirs = Get-Directories -Path 'C:\'
    
  • Use a reference variable. A reference passes a variable's address in memory to a function. When the function changes the variable's data it will be accessible outside of the function but the variable's scope will not of been changed.

    function Get-Directories {
        param ([string] $Path, [ref] $Directories)
        $Directories.Value = Get-ChildItem -Path $Path | where {$_.PsIsContainer}
    }
    
    $myDirs = $null
    Get-Directories -Path 'C:\' -Directories ([ref] $myDirs)
    

Hope this helps. Happy coding :-)

like image 26
2 revs Avatar answered Dec 06 '22 09:12

2 revs