komorebikoboshiのブログ

プログラミング記事(趣味レベル)が多め。

PowerShellの関数の引数を補完する

PowerShellでこんな関数を書いたとして

function Jump-Location{
    param($Target)
    
    $jumpList = @{"SendTo"=([Environment]::GetFolderPath("sendto"));
                  "StartUp"=([Environment]::GetFolderPath("startup"))}
    
    Set-Location -Path $jumpList[$Target]
}

こんな感じで使うのですが

Jump-Location -Target StartUp # スタートアップフォルダにChange Directoryする
Jump-Location SendTo # -Targetは省略できる

ここでStartUpとかSendToとかを補完できたら素敵ですよね。
引数にValidateSet属性を付けるとそれが可能になります。

function Jump-Location{
    param([ValidateSet("SendTo","StartUp")]$Target) # ここを変える
    
    $jumpList = @{"SendTo"=([Environment]::GetFolderPath("sendto"));
                  "StartUp"=([Environment]::GetFolderPath("startup"))}
    
    Set-Location -Path $jumpList[$Target]
}

[ValidateSet(配列)$変数名]とすることで引数が取れる値を配列の要素に限定することができます。(それ以外の値が入力されるとエラーになります)そして指定した値はTABキーで補完できるようになります。

Jump-Location -Target # ここでTABを押すとSendToやStartUpが補完される
Jump-Location # -Targetを省略しても補完される

ステキ!
ところで、Hashのキーを変数に取り出して指定できたらもっと素敵なのですが、

$jumpList = @{"SendTo"=([Environment]::GetFolderPath("sendto"));
              "StartUp"=([Environment]::GetFolderPath("startup"))}
$keys = $jumpList.Keys

function Jump-Location{
    param([ValidateSet($keys)]$Target) # param文は関数の先頭にしか置けない?
    
    Set-Location -Path $jumpList[$Target]
}

としても、

発生場所 行:6 文字:24
+     param([ValidateSet($keys)]$Target)
+                        ~~~~~
パラメーター属性は、定数またはスクリプト ブロックである必要があります。
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock

とダメ出しを受けます。*1がっかり。

*1:Set-Variable keys $jumpList-Option Constant も試してみたけどダメだった