使用Set Item和GetNewClosure创建Powershell函数

使用Set Item和GetNewClosure创建Powershell函数,powershell,scriptblock,Powershell,Scriptblock,我试图构建一个函数,该函数本身可以通过Set Item命令创建函数,在该命令中,我将新函数的scriptblock传递给Set Item的-Value参数。我遇到了一个问题,在scriptblock上使用GetNewClose似乎不起作用,我不知道我做错了什么 在下面的代码中,首先我手动创建一个函数(testFunc),该函数按预期工作,在函数创建后将$x设置为2不会导致函数返回2;相反,它返回1,因为这是创建函数时$x的值。但当我尝试通过make函数执行相同操作时,行为会发生变化 我肯定我忽略

我试图构建一个函数,该函数本身可以通过Set Item命令创建函数,在该命令中,我将新函数的scriptblock传递给Set Item的-Value参数。我遇到了一个问题,在scriptblock上使用GetNewClose似乎不起作用,我不知道我做错了什么

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

我肯定我忽略了一些小东西

> $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? 
线索就在这本书中,但很微妙:

将复制调用者上下文中的所有局部变量 进入模块

GetNewClosure()
似乎只捕获“仅”局部变量,即来自调用者当前作用域的变量。所以试试这个:

function Make-Function {
   $x = $global:x
   $function:global:testFunc2 = {$x}.GetNewClosure()
}
顺便说一句,您可以通过执行以下命令查看
GetNewClosure()
将哪些变量捕获到新创建的动态模块中:

$m = (Get-Command testFunc2).Module
& $m Get-Variable -Scope 0

太棒了,基思!谢谢你的帮助。您的最后一条建议(即获取GetNewClosure()捕获的变量)非常非常有用。如何删除创建为function:global:的函数?我无法使用“删除项”、“清除项”来执行此操作。有什么想法吗?