[英]How can I invoke a scriptblock in the caller's context?
考慮以下呼叫站點:
$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似乎能夠做到這一點。 例如,用ForEach-Object
替換SomeScriptblockInvoker
產生所需的輸出。
我接近使用以下定義:
New-Module m {
function SomeScriptblockInvoker {
param
(
[Parameter(Position = 1)]
[scriptblock]
$Scriptblock,
[Parameter(ValueFromPipeline)]
$InputObject
)
process
{
$InputObject | . $Scriptblock
}
}
} |
Import-Module
使用該定義的呼叫站點的輸出如下:
Local DollarBar
----- ---------
local
modified local value
注意,當它應該是input object
時, DollarBar
是空的。
一般來說,你不能。 scriptblock的調用者無法控制與該scriptblock關聯的SessionState ,並且SessionState(部分)確定執行scriptblock的上下文(有關詳細信息,請參閱Scope部分)。 根據腳本塊的定義位置,其SessionState可能與調用者的上下文匹配,但可能不匹配。
關於執行scriptblock的上下文,有兩個相關的注意事項:
$_
自動變量 $_
包含管道中的當前對象 。 提供給%
的scriptblock的解釋與提供的scriptblock不同.
和&
:
'input_object' | % {$_}
'input_object' | % {$_}
-的價值$_
是'input_object'
,因為腳本塊勢必%
的-Process
參數。 該腳本塊對管道中的每個對象執行一次。 'input_object' | . {process{$_}}
'input_object' | . {process{$_}}
和'input_object' | & {process{$_}}
'input_object' | & {process{$_}}
-的值$_
是'input_object'
因為$_
在腳本塊是一個內部process{}
塊其中用於管道中的每個對象執行一次。 請注意,在使用調用scriptblock時,OP $_
為空.
。 這是因為scriptblock不包含process{}
塊。 scriptblock中的每個語句都隱含地是scriptblock的end{}
塊的一部分。 運行end{}
塊時,管道中不再有任何對象, $_
為null。
.
vs &
vs %
.
, &
,和%
每個使用scriptblock的SessionState調用scriptblock,根據下表有一些不同之處:
+---+-----------------+-----------+-------------------+----------------------+
| | 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{}
塊對應的其他參數。 在OP中通過測試的兩個最可行的選項如下。 請注意,既不在調用者的上下文中嚴格調用scriptblock,而是在使用與scriptblock關聯的SessionState的上下文中調用scriptblock。
更改呼叫站點,以便腳本塊包括process{}
:
$modifiedLocal = 'original local value'
'input object' | SomeScriptblockInvoker {
process {
$modifiedLocal = 'modified local value'
[pscustomobject] @{
Local = $local
DollarBar = $_
}
}
}
$modifiedLocal
並使用OP中的SomeScriptblockInvoker
調用scriptblock。
根據PetSerAl的建議使用%
調用scriptblock。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.