4

在 Perl 中(我多么想念它),我可以检测函数的调用上下文,特别是判断函数的返回值是被丢弃(空上下文)还是分配给标量或列表变量。

这允许一些非常优雅的表达。Powershell中是否有等价物(我还没有找到)?

4

2 回答 2

2

您可以使用 $host.runspace.runningpipelines(或 $host.runspace.GetCurrentlyRunningPipeline())来访问“本地管道”。本地管道有一个“命令”成员。此数组中的每个条目,类型为 Management.Automation.Runspaces.Command,代表一个命令/脚本,它是正在运行的管道的一部分。Runspaces.Command 有一个成员 CommandText,其中包含正在运行的管道的全文(而 $myinvocation 仅具有当前行)。您可以解析 CommandText 以获取诸如 out-null、[void] cast 和分配给 $null 之类的内容。请注意,powershell 解析器记录在一些博客中,可用于帮助解析。

runningpipelines 和 GetCurrentlyRunningPipeline() 都是 RunSpace 的私有成员,因此您需要通过反射访问它们。

于 2013-06-06T21:25:59.890 回答
0

通常,PowerShell 倾向于显式偏好而不是隐式的、上下文相关的行为。例如:

  • 详细输出默认隐藏,但可以使用-Verbose参数或$VerbosePreference变量进行配置。
  • 未使用的输出由主机以默认的基于类型的格式显示,但可以配置为显示具有显式Format-___调用的特定成员。
  • Rename-Item默认情况下不返回更新的文件,但您可以使用该-PassThru参数将它们输出到管道。
  • 将命令的输出保存到变量(例如$x = Get-ChildItem)中,如果没有返回项目,则默认为 null,如果仅返回一个项目,则默认为该项目,如果返回多个项目,则默认为数组;但这可以通过显式请求一个数组来覆盖$x = @(Get-ChildItem)

您可以争辩说,$renamedItems = Rename-Item ...或者Rename-Item ... | Out-Default有时与$renamedItems = Rename-Item ... -PassThru. 然而,很难解释为什么项目$renamedItems在第一次调用中神奇地出现,Rename-Item而它本身什么也没产生。(或者更糟的是,如果碰巧根据分配给的最后一个值是标量还是可枚举值,$variable = Some-Command在一项或多项之间更改其输出。)$variable


$MyInvocation话虽如此,您可以从自动变量中收集大量信息。例如,您可以检查PipelinePositionandPipelineLength属性来确定调用是否是较大管道的一部分,或者使用LineandOffsetInLine属性(可能带有一些解析逻辑)来确定调用输出是否存在分配或强制转换。

用户是否会发现结果一致且可预测是另一回事:)

于 2013-04-25T23:30:03.390 回答