ПРИМЕЧАНИЕ. Я использую PowerShell 2.0 в Windows Vista.
Я пытаюсь добавить поддержку для указания аргументов сборки для psake , но я столкнулся с каким-то странным поведением области видимости переменных PowerShell, касающимся конкретно вызова функций, которые были экспортированы с помощью Export-ModuleMember (который как psake выставляет свой основной метод). Ниже приведен простой модуль PowerShell для иллюстрации (с именем repoCase.psm1):
function Test {
param(
[Parameter(Position=0,Mandatory=0)]
[scriptblock]$properties = {}
)
$defaults = {$message = "Hello, world!"}
Write-Host "Before running defaults, message is: $message"
. $defaults
#At this point, $message is correctly set to "Hellow, world!"
Write-Host "Aftering running defaults, message is: $message"
. $properties
#At this point, I would expect $message to be set to whatever is passed in,
#which in this case is "Hello from poperties!", but it isn't.
Write-Host "Aftering running properties, message is: $message"
}
Export-ModuleMember -Function "Test"
Чтобы проверить модуль, выполните следующую последовательность команд (убедитесь, что вы находитесь в том же каталоге, что и repoCase.psm1):
Import-Module .\repoCase.psm1
#Note that $message should be null
Write-Host "Before execution - In global scope, message is: $message"
Test -properties { "Executing properties, message is $message"; $message = "Hello from properties!"; }
#Now $message is set to the value from the script block. The script block affected only the global scope.
Write-Host "After execution - In global scope, message is: $message"
Remove-Module repoCase
Я ожидал, что блок скрипта, который я передал Test, повлияет на локальную область действия Test. Он находится в «точечном источнике», поэтому любые изменения, которые он вносит, должны быть в рамках действия вызывающей стороны. Однако, это не то, что происходит, это, кажется, влияет на область, где это было объявлено. Вот вывод:
Before execution - In global scope, message is:
Before running defaults, message is:
Aftering running defaults, message is: Hello, world!
Executing properties, message is
Aftering running properties, message is: Hello, world!
After execution - In global scope, message is: Hello from properties!
Интересно, что если я не экспортирую Test как модуль, а просто объявлю функцию и вызову ее, все будет работать так, как я ожидал. Блок сценария влияет только на область действия Test и не изменяет глобальную область.
Я не гуру PowerShell, но может кто-нибудь объяснить мне это поведение?