はじめに
先日に職場で「PowerShellの(関数内での)標準出力は戻り値として扱われる」という話を聞きました。
return文以外も戻り値として扱われるというのが話だけでは理解できなかったので、実際にコードを作って試してみました。
作成したコード
- 以下のコードを実行してみると、return文が無いにもかかわらず、
Write-Output
の結果がそのまま戻り値として扱われていることが分かりました。 -
Write-Output
のリファレンスを見ると以下のように書かれていましたが、このコマンドの結果が戻り値として扱われるケースがあるとは書かれていませんでした。
「指定したオブジェクトをパイプラインに書き込みます。 パイプラインの最後のコマンドの場合 Write-Output は、オブジェクトがコンソールに表示されます。」
- なお、
Write-Host
はコンソールに出力するだけなので、戻り値としては扱われていませんでした。 - またこちらの記事を見ると、「returnに指定したオブジェクト」「標準出力の結果」「Addメソッドの結果」の3つが戻り値に含まれると書かれていました。
-
Add
した結果も戻り値に含まれると、さらに問題がややこしくなりそうですね...
-
test5.ps1
function PrintMessage() {
Write-Host "Print"
Write-OutPut "Message"
& PrintMessage2
}
function PrintMessage2() {
Write-OutPut "PrintMessage2"
}
$retVal = PrintMessage
Write-Host ("retVal: " + $retVal)
実行結果
Print
retVal: Message PrintMessage2
余計な戻り値を生じさせない改善案
Out-Nullを組み合わせる
- パイプラインで
Out-Null
コマンドを呼び出すと、Write-Output
の出力を非表示にするのと同時に、戻り値に入り込むのも防げます。- 以下の例は
Write-Output
と組み合わせていますが、実際にはAdd
した結果が戻り値に入り込まないようにする時に使うのが良いと感じました。
- 以下の例は
test5.ps1
function PrintMessage() {
Write-Host "Print"
Write-OutPut "Message" | Out-Null
& PrintMessage2
}
function PrintMessage2() {
Write-OutPut "PrintMessage2" | Out-Null
}
$retVal = PrintMessage
Write-Host ("retVal: " + $retVal)
実行結果
Print
retVal:
Write-Hostに切り替え
-
Write-Output
からWrite-Host
に切り替えて、戻り値に影響を及ぼさないようにした上でコンソールに出力することができます。-
Write-Output
の結果が戻り値となってしまう問題を解決するには、これが最も現実的な解決策だと思われます。
-
test5.ps1
function PrintMessage() {
Write-Host "Print"
Write-Host "Message"
& PrintMessage2
}
function PrintMessage2() {
Write-Host "PrintMessage2"
}
$retVal = PrintMessage
Write-Host ("retVal: " + $retVal)
実行結果
Print
Message
PrintMessage2
retVal: