Создание функции Powershell с помощью Set-Item и GetNewClosure

Я пытаюсь создать функцию, которая сама может создавать функции с помощью команды Set-Item, где я передаю блок сценария для новой функции параметру -Value команды Set-Item. Я столкнулся с проблемой, когда использование 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? 

person LoganTheSnowEater    schedule 30.11.2014    source источник


Ответы (1)


Подсказка находится в документах MSDN но это тонко:

Любые локальные переменные, находящиеся в контексте вызывающего объекта, копируются в модуль.

GetNewClosure(), по-видимому, захватывает «только» локальные переменные, т. е. из текущей области действия вызывающего объекта. Итак, попробуйте следующее:

function Make-Function {
   $x = $global:x
   $function:global:testFunc2 = {$x}.GetNewClosure()
}

Кстати, вы можете увидеть, какие переменные захвачены GetNewClosure() во вновь созданный динамический модуль, выполнив:

$m = (Get-Command testFunc2).Module
& $m Get-Variable -Scope 0
person Keith Hill    schedule 30.11.2014
comment
Классный Кит! Спасибо за помощь. Ваш последний совет (например, получение переменных, захваченных GetNewClosure()) действительно очень полезен. - person LoganTheSnowEater; 01.12.2014
comment
Как удалить те функции, которые были созданы как function:global: ? Я не могу сделать это, используя remove-item, clear-item. Любые идеи? - person anoopb; 11.08.2016