(PowerShell的5)
我有以下COALESCE函数:您可以将CmdletBinding与未绑定参数结合使用吗?
(更新:删除在process
块中的 “优化” continue
调用)
function Find-Defined {
begin {
$ans = $NULL;
$Test = { $_ -ne $NULL };
}
process {
if ($ans -eq $NULL) {
$ans = $_ |? $Test | Select -First 1;
}
}
end {
if ($ans -ne $NULL) {
return $ans;
}
else {
$Args `
|% { if ($_ -is [Array]) { $_ |% { $_ } } else { $_ } } `
|? $Test `
| Select -First 1 `
| Write-Output `
;
}
}
}
而且这个作品足够好了我在命令行如下:
$NULL, $NULL, 'Legit', 1, 4 | Find-Defined;
$NULL, $NULL | Find-Defined $NULL, @($NULL, 'Value'), 3;
$NULL, $NULL | Find-Defined $NULL $NULL 3 4;
您可能会注意到t我把决策逻辑封装在一个ScriptBlock
变量中。这是因为我想参数化,我开始尝试这个。
[CmdletBinding()]param([ScriptBlock] $Test = { $_ -ne $NULL });
但是,我加了一分钟CmdletBinding
我开始出现错误。该绑定想尝试在参数部分为ScriptBlock
投了一切,所以我加了
[CmdletBinding(PositionalBinding=$False)]
然后它抱怨说,未绑定的参数不能绑定的,所以我说:
param([parameter(Mandatory=$False,Position=0,ValueFromRemainingArguments=$True)][Object[]] $Arguments ...
而且我之后做的任何事情都添加了新的错误。如果我删除了$Test
参数,只是它本地化看看我能做些什么,然后我就开始收到错误开发的第一代,当我有:
The input object cannot be bound to any parameters for the command either
because the command does not take pipeline input or the input and its
properties do not match any of the parameters that take pipeline input.
...即使我有一个process
块。
最后,简单地删除param
声明,把它放回到我喜欢的灵活函数中。
我还是想扩大这个功能同时接受一个ScriptBlock
测试和绑定参数(以及常见的参数,如-Verbose
,如果可能的话)。这样我可以有串合并以及一般的算法:
$Test = { -not [string]::IsNullOrEmpty([string]$_) };
$NULL,$NULL,'','' | Find-Defined -Test $Test $NULL,'','This should be it' 'Not seen'
我缺少的东西?
顺便提一下,'continue'是循环控制指令。很可能,当你将你的函数放在脚本中时,它对你来说意想不到。 – PetSerAl
@PetSerAl:你说得对。在原版中,我添加了一些其他步骤 - 就像没有在'begin'块中指定的'ScriptBlock'一样。我会改回它。 – Axeman