4

Perl では (どうして見逃してしまったのか)、関数の呼び出しコンテキストを検出できました。具体的には、関数の戻り値が破棄されているか (void コンテキスト)、スカラー変数またはリスト変数に割り当てられているかを判断できました。

これにより、非常にエレガントな表現が可能になりました。Powershell に同等のものはありますか (見つけられませんでした)。

4

2 に答える 2

2

$host.runspace.runningpipelines (または $host.runspace.GetCurrentlyRunningPipeline()) を使用して、「ローカル パイプライン」にアクセスできます。ローカル パイプラインには「コマンド」メンバーがあります。Management.Automation.Runspaces.Command 型のこの配列の各エントリは、実行中のパイプラインの一部であるコマンド/スクリプトを表します。Runspaces.Command には、実行中のパイプラインの全文を持つ CommandText メンバーがあります (一方、$myinvocation には現在の行しかありません)。out-null、[void] キャスト、$null への代入などの CommandText を解析できます。PowerShell パーサーはいくつかのブログで文書化されており、解析を支援するために使用できることに注意してください。

runningpipelines と GetCurrentlyRunningPipeline() はどちらも RunSpace のプライベート メンバーであるため、リフレクション経由でアクセスする必要があります。

于 2013-06-06T21:25:59.890 に答える
0

一般に、PowerShell は暗黙的なコンテキスト依存の動作よりも明示的な設定を優先します。例えば:

  • 詳細出力はデフォルトで非表示になっていますが、-Verboseパラメーターまたは$VerbosePreference変数を使用して構成できます。
  • 未使用の出力は、デフォルトのタイプベースのフォーマットでホストによって表示されますが、明示的なFormat-___呼び出しで特定のメンバーを表示するように構成できます。
  • によって更新されたファイルRename-Itemはデフォルトでは返されませんが、-PassThruパラメータを使用してパイプラインに出力することができます。
  • コマンドの出力を変数 (例: $x = Get-ChildItem) に保存すると、項目が返されない場合はデフォルトで null になり、項目が 1 つだけ返された場合は項目が返され、複数の項目が返された場合は配列になります。しかし、これは で配列を明示的に要求することでオーバーライドできます$x = @(Get-ChildItem)

あなたはそれを主張することができ、$renamedItems = Rename-Item ...またはRename-Item ... | Out-Defaultより便利な場合があります$renamedItems = Rename-Item ... -PassThru。しかし、それ自体では何も生成しないのに、アイテム$renamedItemsが最初の呼び出しで魔法のように表示される理由を説明するのははるかに困難です。Rename-Item(さらに悪いことに、最後に割り当てられた値がたまたまスカラーであったか列挙可能な値であった$variable = Some-Commandかに基づいて、1 つのアイテムまたは複数のアイテムの間で出力を変更した場合)。$variable


そうは言っても、$MyInvocation自動変数から多くの情報を収集できます。たとえば、PipelinePositionおよびPipelineLengthプロパティを調べて、呼び出しがより大きなパイプラインの一部であるかどうかを判断したり、LineおよびOffsetInLineプロパティを (おそらく何らかの解析ロジックと共に) 使用して、呼び出しの出力の代入またはキャストがあるかどうかを判断したりできます。

ユーザーが結果に一貫性があり、予測可能であると感じるかどうかは別の問題です:)

于 2013-04-25T23:30:03.390 に答える