PowerShell の最大の特徴と言われた時に、おそらく掲げるべきはパイプラインだと思います。
それが、cmd や Linux/Unix シェルにおけるパイプラインと異なる挙動だったり、オブジェクトを伝搬するという性質も含めて良くも悪くも PowerShell を PowerShell 足らしめているのはパイプラインかなと。
さて、パイプラインが特徴の PowerShell ですが、問題がいくつかあります。その一つが、以下の記事にあるパイプラインの中断処理。
https://winscript.jp/powershell/308winscript.jp
今回は少しその辺をみてみましょう。
目次
StopUpstreamCommandsException
先に結論だけ書くと、Internal なクラスであっても System.Management.Automation.StopUpstreamCommandsException
が一番楽ちんでしょう。
ということで、PowerShell版で書くなら雑にこんな感じで。あえて New-Object
ではなく Add-Type
しています。
中で System.Collections.Queue
を使ってるのはそれほどの意味はありません。入力されたオブジェクトをいいように扱うためです。なので、カウンタ変数を用意してでもお好きなようにやればいいと思います。
この方式なら、Cmdlet でも同様なので好きなように扱えるのもいいでしょう。
はじめは、ReferenceSource見て自分で実装するのでいいんじゃないかなと思いましたが、当然ながら面倒さが上回ったのでやめました。
仕様変更あったらどうしよう
そもそもその場合は、Select-Object
も仕様変わります。もはやその時点で一緒かなと。
Select -Fist 1 の GetSteppablePipeline()
でも PowerShell スクリプトならいいのですが、Cmdlet から PowerShell 関数呼ぶの悲しさしかないですし仕方ないのかなという妥協もあります。
Connect
ちなみにこの Internal Class なやつを Public にしてというリクエストはあります。ワークアラウンドに do{}while()
や Select-Object -First 1
の例もあります。
すでにPowerShell のフィードバックは、UserVoice に移っており、同フィードバックも転載されています。
Enable users to stop pipeline/making StopUpstreamCommandsException public
Votes from Connect: 24
Original Date Submitted: 10/25/2012 1:54:42 PM
Description:
********Contact Information********
Handle: TobiasWeltner
Site Name: PowerShell
Feedback ID: 768650
***************************************
Frequency: Always Happens
Regression: No, this is new to the most ...
なので、Stop-Pipeline
Cmdlet や StopUpstreamCommandsException
のパブリック化がこれに基づきされてほしいですね。Vote しましょう。
End が実行されないのも、フィードバックすればいいと思います。End で何かしらするのはリソース破棄以外にもあり得るので、実際あってほしいでしょう。PowerShell Team の書くスクリプトの中にも Process{} 句で配列にまとめて End{} 句で出力するパターンもあるので。
余談
こういったパイプラインの制限というか、まだまだいけてないシーンはあって、たとえば foreach(){} | ....
もそれです。
Make the foreach statement work with a pipeline
Votes from Connect: 29
Original Date Submitted: 7/21/2011 4:50:05 AM
Description:
********Contact Information********
Handle: Joel -Jaykul- Bennett
Site Name: PowerShell
Feedback ID: 680120
***************************************
Frequency: Always Happens
Regression: No, this is ne...
パイプラインの中断エラーを Write-Error
で出せるようにとかもあります。
Option to output a pipeline terminating error via a Write-Error switch parameter
Votes from Connect: 3
Original Date Submitted: 4/14/2015 6:32:46 PM
Description:
********Contact Information********
Handle: Carl Sörqvist
Site Name: PowerShell
Feedback ID: 1247244
***************************************
Problem Description:
There are three types of errors in Po...
昔記事にした | Out-Null
の遅さなども。
performance of out-null drastically worse then using [void] or assigning result to $null
Votes from Connect: 4
Original Date Submitted: 3/28/2015 6:08:31 AM
Description:
********Contact Information********
Handle: JasonHorner
Site Name: PowerShell
Feedback ID: 1208677
***************************************
Frequency: PowerShell
Regression: gci | out-null
[void](gci)
$null...
あとは、Where-Object
などで {}
抜きで自動変数 $_ にアクセスしたいという例など。実際これほしいですよね。
$_ should be accessible without curly brackets with Where-Object
Votes from Connect: 5
Original Date Submitted: 10/30/2014 6:04:29 AM
Description:
********Contact Information********
Handle: Peter M10
Site Name: PowerShell
Feedback ID: 1014939
***************************************
Frequency: Always Happens
Regression: Yes, this happens in all previou...
まとめ
リフレクション最高 (