考虑以下 call 站点:
$modifiedLocal = 'original local value'
'input object' | SomeScriptblockInvoker {
$modifiedLocal = 'modified local value'
[pscustomobject] @{
Local = $local
DollarBar = $_
}
}
$modifiedLocal
我想实现
SomeScriptblockInvoker
这样调用站点上的函数输出如下:
Local DollarBar
----- ---------
local input object
modified local value
PowerShell似乎可以做到这一点。例如,用
SomeScriptblockInvoker
替换ForEach-Object
会产生恰好所需的输出。我使用以下定义进行了详细介绍:
New-Module m {
function SomeScriptblockInvoker {
param
(
[Parameter(Position = 1)]
[scriptblock]
$Scriptblock,
[Parameter(ValueFromPipeline)]
$InputObject
)
process
{
$InputObject | . $Scriptblock
}
}
} |
Import-Module
使用该定义的 call 站点的输出如下:
Local DollarBar
----- ---------
local
modified local value
请注意,
DollarBar
应该为input object
时为空。(gist of Pester tests to check for correct behavior)
最佳答案
通常,您不能。脚本块的调用者无法控制与该脚本块相关联的SessionState,并且SessionState确定(部分)确定执行脚本块的上下文(有关详细信息,请参见“作用域”部分)。根据脚本块的定义位置,其SessionState可能与调用者的上下文匹配,但可能不匹配。
范围
关于执行脚本块的上下文,有两个相关的注意事项:
Here is a good explanation of how this works。
$_
自动变量$_
contains the current object in the pipeline。提供给%
的脚本块的解释与提供的.
和&
的脚本块不同:'input_object' | % {$_}
-$_
的值为'input_object'
,因为脚本块绑定(bind)到%
的-Process
参数。该脚本块对管道中的每个对象执行一次。 'input_object' | . {process{$_}}
和'input_object' | & {process{$_}}
-$_
的值为'input_object'
,因为脚本块中的$_
位于process{}
块内,该块对管道中的每个对象执行一次。 请注意,在OP中,使用
$_
调用脚本块时,.
为空。这是因为脚本块不包含process{}
块。脚本块中的每个语句都隐式属于脚本块end{}
块的一部分。到运行end{}
块时,管道中不再有任何对象,并且$_
为null。.
vs &
vs %
.
,&
和%
各自使用脚本块的SessionState调用脚本块,但根据下表有所不同:+---+-----------------+-----------+-------------------+----------------------+
| | Name | Kind | interprets {} as | adds scope to stack |
+---+-----------------+-----------+-------------------+----------------------+
| % | ForEach-Object | Command | Process block | No |
| . | dot-source | Operator | scriptblock | No |
| & | call | Operator | scriptblock | Yes |
+---+-----------------+-----------+-------------------+----------------------+
%
命令具有与Begin{}
和End{}
块相对应的其他参数。 最可行的选择
传递the tests in OP的两个最可行的方法如下。请注意,两者均未严格在调用者的上下文中调用脚本块,而是在使用与脚本块相关联的SessionState的上下文中调用脚本块。
选项1
更改 call 站点,以便脚本块包含
process{}
:$modifiedLocal = 'original local value'
'input object' | SomeScriptblockInvoker {
process {
$modifiedLocal = 'modified local value'
[pscustomobject] @{
Local = $local
DollarBar = $_
}
}
}
$modifiedLocal
并在OP中使用
SomeScriptblockInvoker
调用脚本块。选项2
使用
%
作为suggested by PetSerAl调用脚本块。关于function - 如何在调用者的上下文中调用脚本块?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46428736/