有没有where-object比使用父范围变量更好的方法将信息传递到过滤器脚本中的脚本块?
背景:
我有一个脚本,查找未签入和/或修改的源文件与源代码控制,并有一个参数,允许它进行更详尽的搜索.我where-object在一些地方使用脚本块对象包含在脚本范围的变量中,我根据脚本的输入参数自定义该变量.
因此,如果您要求彻底搜索,过滤器会将候选文件与所有TFS文件进行比较,以查看该文件是否不在源代码控制中,如果您选择不太彻底的搜索,则过滤器只会与已检查的内容进行比较 - 输出文件以查看文件是否已修改但未检出.
自定义脚本块指的是包含对源控件执行查询的结果的脚本范围变量.
所以我的问题是我想摆脱一个全局(脚本级)变量,并将所有必要的信息作为脚本块的参数传递给脚本块.如果我正在使用invoke-command,我会使用ArgumentList参数来执行此操作. Where-Object似乎没有那个.在脚本块中使用父范围变量引用的一个缺点是我无法更改这些变量,所以我不能进行延迟初始化(或者至少我还没弄清楚如何,不是一个专家Powershell的范围规则.)
只是为了扩展Keith提到的内容,你可以这样做:
ps> $x=2
ps> 1..5 | where (& {param($v); { $_ -eq $v }.getnewclosure() } $x )
2
Run Code Online (Sandbox Code Playgroud)
我试图关闭over implict $args以保存param声明,但$args似乎免于捕获.它更有可能被捕获但只是被踩到了.
$x很容易被另一个函数调用替换为(get-x).
本质上我正在调用一个脚本块,它返回一个脚本块,该脚本块关闭外部scriptblocks参数.与Keiths基本相同的实现,只是更多的succint [和迟钝.] Lambdas为胜利.
我只希望有一种更简洁的方法来获得闭包语义.也就是说,我很高兴这种方法得到了投入而不是投入.
-Oisin
您可以创建一个临时范围并GetNewClosure()在scriptblock上使用该方法让它围绕scriptblock中使用的变量创建一个闭包,例如:
function FilterProcs([scriptblock]$scriptblock)
{
Get-Process | Where $scriptblock
}
$name = 'Notepad'
& {
$name = 'PowerShell'
FilterProcs {$_.Name -eq $name}.GetNewClosure()
}
$name
Run Code Online (Sandbox Code Playgroud)
在这种情况下,内部修改$name仅在本地而不是在脚本范围内看到.可能有更好的方法,但我认为这对你有用.
BTW这是另一种使用Foreach-Object cmdlet进行过滤的方法:
function FilterProcs([scriptblock]$scriptblock, [object[]]$argumentList)
{
Get-Process | Foreach {if (&$scriptblock @argumentList){$_}}
}
FilterProcs {param($name, $id) ($_.Name -match $name -and $_.Id -eq $id)} `
-ArgumentList 'PowerShell_ISE',$pid
Run Code Online (Sandbox Code Playgroud)
PS很高兴看到你保持PowerShellin'.:-)
| 归档时间: |
|
| 查看次数: |
2881 次 |
| 最近记录: |