I read that variables inside the scope of a function are accessible in the current scope when the function script is dot-sourced.
Is it true? It's very strange, and unusual I think...
Can me clarify the reasons of this. Example, my-f
sets $my-f-var
to some integer, let's say 2:
PS1> . .\my-f-script.ps1
PS1> my-f
PS1> $my-f-var
2
I would expect that $my-f-var
is not accessible because inside the function! Is there a way to make variables private, or a way to call the function without dot-sourcing its script?
Variables within the function are local to that scope unless you dot the invocation of the function name. When you dot source a script, the top-level script variables are effectively imported into the current scope along with the function definitions e.g.:
Note that ${my-f-var} isn't defined in the local scope. However, if i 'dot' the invocation of the function then its contents are run in the current scope e.g.:
In this case, the variable set in the function is set in the current (invoking) scope because of the 'dot' used to invoke it.
A couple of more points: you can access variables at various scopes using either
Get-Variable -scope
or the more convenient (if less flexible) global, script, local and private modifiers. When you access a variable inside a function where the variable is defined in a higher scope, you can read it just fine. But when you set it, PowerShell essentially does a "copy-on-write" of the variable - creating a new copy scoped from that function downward (ie to the other functions it calls). If you really want to modify a higher scoped variable you can use $global:Foo or $script:Foo to modify at those scopes.The
local
scope comes in handy if you want to avoid inadvertently using a variable defined outside of your function. Another MVP brought this up at the last MVP summit and it seems like one of those "best practice" tips. Here's the scenario:Note that in this case the use of
$foo
inside the function is a typo but coincidentally there is a variable by that typo'd name. This was not the intent of the function and it is not working correctly although that is hard to see in this case. Below, we can use thelocal
specifier to make sure the function only looks within the local scope for the variable. It doesn't find it because of the typo but at least the error is a bit easier to spot now.The
private
scope is useful when you don't want certain variables to be visible to the other functions that your function calls.