4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PowerShell の return は変数に格納したほうがエラー処理的に安全だという話

Last updated at Posted at 2020-08-13

いわゆる early-return というものを PowerShell でやろうとしたときにハマったのでメモ。

環境


Name                           Value
----                           -----
PSVersion                      7.0.3
PSEdition                      Core
GitCommitId                    7.0.3
OS                             Microsoft Windows 10.0.18362
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

経緯

PowerShell では見出しが重複した csv を ConvertFrom-Csv しようとするとエラーが出ます。

PS> cat .\target.csv
AA,AA,BB
10,20,30
40,50,60

PS> cat target.csv | ConvertFrom-Csv
ConvertFrom-Csv: The member "AA" is already present.

しかし次の関数を実行してみると……

function func1 {
    if($true){
        return (cat target.csv | ConvertFrom-Csv)
    }
    Write-Output "ここは出力されてほしくない"
}

コメント 2020-08-13 113407.png
 !?

どうも return に失敗すると return 処理が無視されて 以降の行に処理が移っている様子。-ErrorAction パラメータに Stop を指定しても関係ないようです。

function func2 {
    if($true){
        return (cat target.csv | ConvertFrom-Csv -ErrorAction Stop)
    }
    Write-Output "ここは出力されてほしくない"
}

コメント 2020-08-13 113444.png

明示的に Write-Output するとその行でエラーとして処理が止まるようです。しかし記述を簡略化するための early-return で文字数が増えるのは本末転倒……

function func3 {
    if($true){
        cat target.csv | ConvertFrom-Csv | Write-Output
        return
    }
    Write-Output "ここは出力されてほしくない"
}

コメント 2020-08-13 113517.png

変数に格納するようにしたらちゃんとエラー扱いになりました。少し記述が減ります。

function func4 {
    if($true){
        $ret = (cat target.csv | ConvertFrom-Csv)
        return $ret
    }
    Write-Output "ここは出力されてほしくない"
}

コメント 2020-08-13 113548.png

変数に格納すればよいことがわかったので、 return $() とするのが最も簡単ですね。

function func5 {
    if($true){
        return $(cat target.csv | ConvertFrom-Csv)
    }
    Write-Output "ここは出力されてほしくない"
}

コメント 2020-08-13 113616.png

結局、$ 1つ加えるだけで良かったのでした(しかし Qiita のシンタックスハイライト的にはエラー…?)。

結論

return 内容は変数に格納するべし。

return 処理自体がなかったことになるのは結構な罠ですね。ドキュメント にも () はその中をすべて評価してから以降にパイプするという以上の説明がないので慌てました。心臓に悪い……。

4
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?