PowerShell: передача блоков в качестве параметров функциям - PullRequest
10 голосов
/ 01 декабря 2009

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

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
}

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

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

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

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

1 Ответ

15 голосов
/ 01 декабря 2009

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

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

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

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

A {Write-Host 3}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...