使当前项($ _ / $ PSItem)可用于模块函数中的scriptblock参数

问题描述 投票:2回答:1

基本上我试图让下面的“内联if语句”功能工作(credit here

Function IIf($If, $Then, $Else) {
    If ($If -IsNot "Boolean") {$_ = $If}
    If ($If) {If ($Then -is "ScriptBlock") {&$Then} Else {$Then}}
    Else {If ($Else -is "ScriptBlock") {&$Else} Else {$Else}}
}

使用PowerShell v5它似乎不适合我,并称之为

IIf "some string" {$_.Substring(0, 4)} "no string found :("

给出以下错误:

You cannot call a method on a null-valued expression.
At line:1 char:20
+ IIf "some string" {$_.Substring(0, 4)} "no string found :("
+                    ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

因此,作为一个更普遍的问题,如何让$_可用于传递给函数的scriptblock?

我有点尝试跟随this answer,但它似乎意味着将它传递给一个单独的过程,这不是我正在寻找的。

更新:似乎问题是我在模块中而不是直接在脚本/ PS会话中具有该功能。一个解决方法是避免将它放在模块中,但我觉得模块更便携,所以我想找到一个解决方案。

powershell module
1个回答
2
投票

虽然我没有解释您的症状,但有两个值得做出改变:

  • 不要试图直接分配给$_;它是PowerShell控件下的自动变量,并不是由用户代码设置的(即使它可能有效,但不能依赖它)。 相反,使用ForEach-Object cmdlet通过其$_参数隐式设置-InputObject
  • 使用-is运算符和类型文字,如[Boolean],而不是类型名称,如"Boolean"
Function IIf($If, $Then, $Else) {
  If ($If) { 
    If ($Then -is [scriptblock]) { ForEach-Object -InputObject $If -Process $Then } 
    Else { $Then } 
  } Else {
    If ($Else -is [scriptblock]) { ForEach-Object -InputObject $If -Process $Else }
    Else { $Else }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.