2017-02-03 172 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

也不知道。好一個! –