Splatting が便利

2020/04/18

先日 GitHub で他の方のソースコードをみている時にこの機能を知りましたので、同じように知らない人が居ればと思い紹介。

Splatting とは

公式にはこのように書いてありました。

スプラッティングは、パラメーター値のコレクションをまとめてコマンドに渡す手法です。Windows PowerShell はコレクションのそれぞれの値をコマンドのパラメーターに関連付けます。スプラットされたパラメーター値は、名前付きスプラッティング変数に格納されます。名前つきスプラッティング変数は普通の変数のように見えますが、ドル記号 ($) の代わりにアットマーク (@) で始まります。アットマークは Windows PowerShell に対して、引数が単一の値ではなくコレクションとして渡されることを伝えます。

スプラッティングはコマンドを短くし、読みやすくします。スプラッティング値は別のコマンドの呼び出しで再利用できます。また、スプラッティングを利用して、パラメーター値を $PSBoundParameters 自動変数から他のスクリプトや関数に渡すことができます。

記法

Windows PowerShell 3.0 以降では、コマンドの全パラメーターを次のように表せるそうです。

<CommandName> <optional parameters> @<HashTable> <optional parameters>

<CommandName> <optional parameters> @<Array> <optional parameters>

よく使いそうな例

可読性が良くなるので使っているという事もありますが、例えば自作の関数で引数が多いときや、条件によって動作を変える時に使い始めています。

次の関数は、引数で Param1, Param2, Param3 に数値を渡すと足し算の練習?をして、-Exec スイッチを入れると実際に足し算を行う関数です。

function Get-ParamSum 
{
    Param(
        [CmdletBinding()]
        [Parameter()]
        [int]$Param1 = 0,
        [Parameter()]
        [int]$Param2 = 0,
        [Parameter()]
        [int]$Param3 = 0,
        [Parameter()]
        [switch]$Exec        
    )
    Write-Host -NoNewline ('{0} + {1} + {2}' -f $Param1, $Param2, $Param3)
    if ($Exec) {
        Write-Host (' = {0}' -f ($Param1 + $Param2 + $Param3))
    }
}

例えば、時分秒を合計して、日付が奇数なら -Exec スイッチを付けるとする

ダラダラ書いてみた例

if(((Get-Date -UFormat %d) % 2) -eq 0) {
    Get-ParamSum -Param1 (Get-Date -UFormat %H) -Param2 (Get-Date -UFormat %M) -Param3 (Get-Date -UFormat %S)
} else {
    Get-ParamSum -Param1 (Get-Date -UFormat %H) -Param2 (Get-Date -UFormat %M) -Param3 (Get-Date -UFormat %S) -Exec
}

Splatting を使って書いてみた例

$splatting = @{
    Param1 = Get-Date -UFormat %H
    Param2 = Get-Date -UFormat %M
    Param3 = Get-Date -UFormat %S
}

if(((Get-Date -UFormat %d) % 2) -eq 1) {
    $splatting.Set_Item('Exec', $true)
}

Get-ParamSum @splatting