2010年3月4日木曜日

インポート後の関数の挙動

ScriptBlockを引数に持つような関数を、
モジュールマニフェストファイルを介してImport-Moduleで取り込むと、
ドットソースで読み込んだ場合と違はう動作をしてしまうようです。

モジュールマニフェストの作成方法については、こちらの投稿をどうぞ。

以下、検証サンプルコードです。

ソースコード:
# ファイル名:Test-ScriptBlock.ps1
function Test-ScriptBlock
{
[ScriptBlock]$block = $args[1]
Get-ChildItem -Path $args[0] | %{ '[{0}]:[{1}][{2}]' -f $_.Name, ( $_.Name -like "*a*" ), ( &$block ) }
}

PowerShellのコンソール:

PS> # Import-Moduleでファイルを直接取り込む。
PS> Import-Module .\Test-ScriptBlock.ps1 -Verbose
詳細: パス 'Test-ScriptBlock.ps1' からモジュールを読み込んでいます。
詳細: スクリプト ファイル 'Test-ScriptBlock.ps1' をドット ソース形式で読み込んでいます。

PS> Test-ScriptBlock $Env:PROGRAMFILES { $_.Name -like "*a*" }
結果出力( [アイテム名][True][True]または[アイテム名][False][False] )

PS> # Import-Moduleで、モジュールマニフェストを介してファイルを取り込む。
PS> # Test-ScriptBlock.ps1を含むモジュールマニフェストを作成(.\manifest.psd1)
PS> New-ModuleManifest
PS> Import-Module .\manifest.psd1 -Verbose
詳細: 関数 'Test-ScriptBlock' をインポートしています。
PS> Test-ScriptBlock $Env:PROGRAMFILES { $_.Name -like "*a*" }
結果出力( [アイテム名][True][False]になるものが存在する )
PS> # ↑引数を介して渡したスクリプトブロックの実行結果は常にFalse

PS> Test-ScriptBlock $Env:PROGRAMFILES { -not ( $_ ) }
結果出力( [アイテム名][-----][True])
PS> # ↑$_にオブジェクトが正しく渡されていないことを意味する


上記サンプルだけでは詳細は分かりませんが、
とりあえずは以下のことが言えそうです。
・ドットソースで取り込んだ関数の状態≠インポート後の関数の状態
・インポート後の関数は挙動がおかしい?

新しいことが分かったら関連のエントリーを作成することとします。

関連投稿:
PowerShellの「モジュール」について、その2