2017-02-03 71 views
1

我无法从scriptblocks内理解范围。我正在计算某种封闭式系统,但似乎无法使其工作。PowerShell脚本块变量范围

我有一个脚本块,需要一个PARAM并返回另一个脚本块:

$sb1 = { 
    Param($Message1); 
    Write-Host $Message1; 
    { 
     Param($Message2); 
     Write-Host ($Message1 + " " + $Message2); 
    } 
} 

为了获得内部脚本块,我可以调用$ SB1,如:$sb2 = & $sb1 -Message1 "Message1" 此相呼应,“消息1”,所以我们知道参数是绑定。现在

,我可以调用$ SB2,如:& $sb2 -Message2 "Message2"

我本来期望“的消息2消息1”,但它只是写道:“消息2”来代替。

有没有办法访问$ Message1变量? 我不能使用本地或脚本变量,因为会有不同Message1的内部脚本块的多个实例。

这是从实际的外壳实际输出:

PS C:\> $h1 = { Param($Message1); Write-Host $Message1; { Param($Message2); Write-Host ($Message1 + " " + $Message2); } } 
PS C:\> $h2 = & $h1 -Message1 "Message1" 
Message1 
PS C:\> $h2 
Param($Message2); Write-Host ($Message1 + " " + $Message2); 
PS C:\> & $h2 -Message2 "Message2" 
Message2 
+0

我会更新与我实际运行的问题。虽然它非常相似。 – wensveen

+0

啊,错过了返回值的分配。好吧,现在有道理:) – Joey

回答

4

你需要明确create a closure

$sb1 = { 
    Param($Message1); 
    Write-Host $Message1; 
    { 
     Param($Message2); 
     Write-Host ($Message1 + " " + $Message2); 
    }.GetNewClosure() 
} 

然后,它为我的作品:

PS> $2 = & $sb1 One 
One 
PS> & $2 Two 
One Two 
+0

好的,哇。这完全有道理。我从来不知道ScriptBlock实际上有一个GetNewClosure方法。大多数语言不是关于闭包的明确说明:) – wensveen

+0

有时选择可以很好。我写了脚本,在那里我使用scriptblocks来访问我知道在那里的变量,并且在那里有一个闭包会很烦人。但是,通常它是自动的或者根本不支持:-) – Joey

+0

也不知道。好一个! –