Suppose you have defined two functions in a module (i.e. a .psm1
file):
function f1{
param($x1)
$a1 = 10
f2 $x1
}
function f2{
param($x2)
$a2 = 100
& $x2
}
Now suppose you run the following:
PS C:\> $a0 = 1
PS C:\> $x0 = {$a0+$a1+$a2}
PS C:\> f1 $x0
1
$x2
keeps the context of the command line despite being invoked inside $f2
. This holds if you change &
to .
.
Replacing $xn
with $xn.GetNewClosure()
in the module then calling f1
captures the value of 100
but not 10
:
PS C:\> f1 $x0
101
PS C:\> f1 $x0.GetNewClosure
101
This happens because calling .GetNewClosure()
inside f2
"overwrites" the value of $a1
captured in f1
.
Is there a way to selectively capture variables in scriptblocks? Working from the example, is there a way to capture both $a1
inside f1
and $a2
inside f2
?
Further Reading
PowerShell scopes are not simple. Consider the possibilities from this incomplete list of factors:
- there can be any combination of global and module scope hierarchies active at any time
.
and&
invocation affects scope differently,- the sophisticated flow control afforded by the pipeline means that multiple scopes of the
begin
,process
, andend
scriptblocks of different or the same scope hierarchies, or even multiple invocations of the same function can be active simultaneously
In other words, a working description of PowerShell scope resists simplicity.
The about_Scopes documentation suggests the matter is far simpler than it, in fact, is. Perhaps analysing and understanding the code from this issue would lead to a more complete understanding.