PowerShell: передача блоков в качестве параметров для функций

Я объясню свой вопрос на примере. Пусть в С# следующий код:

void A(Action block)
{
 B(() =>
 {
  Console.WriteLine(2);
  block();
 });
}

void B(Action block)
{
 Console.WriteLine(1);
 block();
}

void Main()
{
 A(() =>
 {
  Console.WriteLine(3);
 });
}

Вывод этого кода:

1
2
3

Теперь я хочу написать этот код в PowerShell:

function A($block) {
    B {
        2
        . $block
    }
}

function B($block) {
    1
    . $block
}

A {
    3
}

Однако этот код вызывает переполнение глубины вызова:

Ошибка script из-за глубины вызова переполнение. Глубина вызова достигла 1001 и максимальный - 1000.

Я обнаружил, что если я изменю имя параметра функции B, он будет работать.

Это функция или ошибка (или и то, и другое)? Как я могу выполнить эту работу в PowerShell без уникальных параметров по функциям?

Ответ 1

Да, вы собираетесь рекурсивно, потому что ссылка $block в скриптблоке, переданная в функцию B, получает оценку в контексте функции B и в результате оценивает значение параметра B $block.

Если вы не хотите изменять имя параметра (не вините вас), вы можете заставить PowerShell создать новое замыкание в A, чтобы захватить значение $block в функции A, например:

function A($block) 
{    
     B {Write-Host 2; &$block}.GetNewClosure()
}

function B($block) 
{
    Write-Host 1
    &$block
}

A {Write-Host 3}