(Powershell 5)
У меня есть следующие Coalesce функции:Можете ли вы объединить CmdletBinding с несвязанными параметрами?
(UPDATE:. Убрано "оптимизированный" continue
вызов в process
блоке)
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'
я упускаю что-то?
BTW, 'continue' является инструкцией по управлению циклом. Очень вероятно, что он будет вести себя непредсказуемо для вас, когда вы поместите свою функцию в скрипт. – PetSerAl
@PetSerAl: Вы правы.В обезьянье с оригиналом я добавил несколько других шагов - как будто не было 'ScriptBlock', указанного в блоке' begin'. Я изменю его. – Axeman