Powershell запускает скрипт-блок - область действия, точечный поиск - PullRequest
0 голосов
/ 15 ноября 2018

Я хочу написать функцию, которая принимает блок сценариев в качестве параметра и выполняет этот блок сценариев в области, в которой он был вызван.

Команда Measure - это пример поведения, которое мне хотелось бы.Скриптблок работает с той же областью действия, что и сама Measure-Command.Если блок сценария ссылается на переменную в этой области, сценарий может изменить ее.

В приложении приведен образец блока сценария, который увеличивает переменную $ a.При вызове Measure-Command переменная увеличивается.Но при вызове функциями Wrapper переменная не будет увеличиваться - если только я не укажу точечный источник, при вызове функции Wrapper и самой функции Wrapper используется точечный источник.

function Wrapper1
{
    param( $scriptBlock )
    $startTime = Get-Date
    Write-Output ( "{0:HH:mm:ss} Start script" -f $startTime )
    & $scriptBlock
    $endTime = Get-Date
    Write-Output ( "{0:HH:mm:ss} End script - {1:c} seconds elapsed" -f $endTime, ( $endTime - $StartTime ) )
}

function Wrapper2
{
    param( $scriptBlock )
    $startTime = Get-Date
    Write-Output ( "{0:HH:mm:ss} Start script" -f $startTime )
    . $scriptBlock
    $endTime = Get-Date
    Write-Output ( "{0:HH:mm:ss} End script - {1:c} seconds elapsed" -f $endTime, ( $endTime - $StartTime ) )
}

$a = 1
Write-Output "Initial state: `$a = $a"

Measure-Command { $a++ } | Out-Null
Write-Output "Measure-Command results: `$a = $a"

Wrapper1 { $a++ }
Write-Output "Wrapper1 results: `$a = $a"

. Wrapper1 { $a++ }
Write-Output "dot-sourced Wrapper1 results: `$a = $a"

Wrapper2 { $a++ }
Write-Output "Wrapper2 results: `$a = $a"

. Wrapper2 { $a++ }
Write-Output "dot-sourced Wrapper2 results: `$a = $a"

Результат выполненияэтот код:

Initial state: $a = 1
Measure-Command results: $a = 2
13:44:49 Start script
13:44:49 End script - 00:00:00 seconds elapsed
Wrapper1 results: $a = 2
13:44:49 Start script
13:44:49 End script - 00:00:00.0157407 seconds elapsed
dot-sourced Wrapper1 results: $a = 2
13:44:49 Start script
13:44:49 End script - 00:00:00 seconds elapsed
Wrapper2 results: $a = 2
13:44:49 Start script
13:44:49 End script - 00:00:00 seconds elapsed
dot-sourced Wrapper2 results: $a = 3

Хотя этот последний вариант работает, я бы хотел избежать синтаксиса точка-источник, вызывающего Wrapper2.Это возможно?Команда Measure не использует синтаксис точка-источник, поэтому кажется, что это возможно.

1 Ответ

0 голосов
/ 15 ноября 2018

PetSerAl , как он обычно делает, дал краткий комментарий в кратком комментарии к вопросу:

Помещение функции в модуль ,наряду с точечным вызовом аргумента блока сценария решает проблему:

$null = New-Module {
  function Wrapper {
    param($ScriptBlock)
    . $ScriptBlock
  }
}

$a = 1
Wrapper { $a++ }

$a

Выше приведено 2, доказывающее, что блок сценария выполняется в области вызывающей стороны .

Для объяснения того, почему это работает и почему это необходимо, см. этот ответ на связанный вопрос.

Примечание : вышеуказанный подходне распространяется на pipe use, где вы захотите передать блоки скриптов, которые ожидают использовать автоматическую переменную $_ для ссылки на объект под рукой (например,
1, 2, 3 | Wrapper { $_ ... }; для поддержкиВ этом случае необходим обходной путь - см. этот ответ .

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