注: Windows Vista で PowerShell 2.0 を使用しています。
ビルド引数をpsakeに指定するためのサポートを追加しようとしていますが、特に Export-ModuleMember を使用してエクスポートされた関数の呼び出しを処理する奇妙な PowerShell 変数スコープ動作に遭遇しました (これは 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 の第一人者ではありませんが、誰かがこの動作を説明してくれませんか?