2011年12月27日火曜日

◆パイプライン中の処理かどうかを判定する(挫折)

関数がパイプラインで使われているのか、どうでないのかを判定する。

調べてみると「$MyInvocation.PipelineLength」あたりを使うのが一般的みたいだ。

こんな感じ。

001
002
003
004
005
006
007
008
009
010
011
012
013

function test
{
 
param($inputobject
)
 
if($MyInvocation.PipelineLength -gt 1
)
  {
   
$input | ogv -Title パイプライン
  }else
{
   
$inputobject | ogv -Title パラメータ
  }
}


ps | 
test
test
 -inputobject (ps)

一見OKなのだが、これではうまく判定できないケースがある。
例えば、

  1. (ps) | test

または、

  1. $temp = ps
  2. $temp | test

などと指定すると、「PipelineLength」は1になってしまうのである。

果たしてこれは正しい結果なのだろうかとちょっと疑問にも思うが、なんにせよこれでは使えない。
色々調べてみたが、他に方法もなさそう。

ん~、パイプラインは難しい。


牟田口さんからヒントを頂き$inputでの判定を検証しました。
判定自体はよさそうです。
ただ、$inputはBeginブロックで判定できないのが若干使いづらいかもしれません。
(Firstブロックみたいな奴があると便利なのですが・・・)
パイプライン入力が1つだけであれば、$PSBoundParametersでその存在を確認する方法で良いかもしれません。

また、ちょっと見落としていたのですが「$myinvocation.ExpectingInput」と言う奴が使えそうな感じにも見えます。

2 件のコメント:

  1. $input.MoveNext()がTrueならパイプライン、Falseならパラメータ、という判定はどうでしょう?
    そのあと$input.Reset()すれば列挙もできますし。

    @()をパイプラインで渡すとFalseになってしまいますが、パイプラインからは何も受け取ってないという意味では間違いではない気もします。

    返信削除
  2. 素早いコメントありがとうございます。(^^
    成る程$inputですかぁ、ちょっと検証してみますね。

    返信削除