使用Set-Item和GetNewClosure创建Powershell函数

Log*_*ter 4 powershell scriptblock

我正在尝试构建一个函数,它本身可以通过Set-Item命令创建函数,我将新函数的scriptblock传递给Set-Item的-Value参数.我遇到一个问题,在脚本块上使用GetNewClosure似乎不起作用,我只是不知道我做错了什么.

在下面的代码中,首先我手动创建一个函数(testFunc)按预期工作,在函数创建后将$ x设置为2将不会导致函数返回2; 相反,它返回1,因为这是创建函数时$ x的值.但是当我尝试通过make-function函数执行相同操作时,行为会发生变化.

我敢肯定我忽视了一些小事.

> $x = 1
> $block = {$x}.GetNewClosure()
> Set-Item function:global:testFunc -Value $block
> testFunc
1 

> $x = 2
> testFunc
1 # still 1 because of GetNewClosure - this is expected behavior

> $x = 1
> function make-function { $block2 = {$x}.GetNewClosure()
       Set-Item function:global:testFunc2 -Value $block2
  }
> make-function
> testFunc2
1 

> $x = 2
> testFunc2
2 # Why is it not returning 1 in this case? 
Run Code Online (Sandbox Code Playgroud)

Kei*_*ill 6

线索在MSDN文档中,但它很微妙:

将调用者上下文中的任何局部变量复制到模块中.

GetNewClosure()似乎捕获"仅"局部变量,即来自调用者当前范围的变量.试试这个:

function Make-Function {
   $x = $global:x
   $function:global:testFunc2 = {$x}.GetNewClosure()
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,您可以GetNewClosure()通过执行以下操作来查看新创建的动态模块中捕获的变量:

$m = (Get-Command testFunc2).Module
& $m Get-Variable -Scope 0
Run Code Online (Sandbox Code Playgroud)