7

PowerShell クロージャーは関数の定義をキャプチャしていないようです。

PS C:\> function x() { Write-Host 'original x' }
PS C:\> function x-caller-generator() { return { Write-host 'Calling x!'; x }.GetNewClosure() }
PS C:\> $y = x-caller-generator
PS C:\> & $y
Calling x!
original x
PS C:\> function x() { Write-Host 'new x' }
PS C:\> & $y
Calling x!
new x

関数の定義をキャプチャする方法はありますか?

私が実際に経験しているのは、クロージャーを作成することですが、クロージャーが実行されると、関数は何らかの形で範囲外になります。(ビルド スクリプト用のpsakeモジュールが行っているのは奇妙なことです。) 次のようなものです。

PS C:\> function closure-maker () {
>>     function x() { Write-Host 'x!' }
>>
>>     return { Write-host 'Calling x'; x }.GetNewClosure()
>> }
>>
PS C:\> $y = closure-maker
PS C:\> & $y
Calling x
The term 'x' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:3 char:39
+     return { Write-host 'Calling x'; x <<<<  }.GetNewClosure()
    + CategoryInfo          : ObjectNotFound: (x:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

注: PowerShell 2.0 を使用していますが、何か新しいことがあれば 3.0 の回答に興味があります。

4

2 に答える 2

0

少し修正すると、最初の例が機能します。

clear
function x() { Write-Host 'original x' }
function x-caller-generator() { 
      $xFunc = $function:x; # instead of Get-Item
      return { Write-host 'Calling x!'; & $xFunc }.GetNewClosure() 
}
$y = x-caller-generator
& $y
function x() { Write-Host 'new x' }
& $y

出力:

Calling x!
original x
Calling x!
original x

PowerShell には、実際には動作が異なる似たようなものが多すぎます。$function プレフィックスを使用して、関数オブジェクトを取得できます。Get-Item と同じように機能すると思われるかもしれませんが、そうではありません...

于 2016-06-06T10:02:33.110 に答える