Кстати, в прошлый раз я запутался PowerShell нетерпеливо разворачивает коллекции, Кейт резюмировал эту эвристику следующим образом:
Помещение результатов (массива) в выражение группировки (или подвыражение, например, $ ()) снова дает право на развертывание.
Я принял этот совет близко к сердцу, но все еще не могу объяснить некоторые эзотерические вопросы. В частности, оператор Format, похоже, не играет по правилам.
$lhs = "{0} {1}"
filter Identity { $_ }
filter Square { ($_, $_) }
filter Wrap { (,$_) }
filter SquareAndWrap { (,($_, $_)) }
$rhs = "a" | Square
# 1. all succeed
$lhs -f $rhs
$lhs -f ($rhs)
$lhs -f $($rhs)
$lhs -f @($rhs)
$rhs = "a" | Square | Wrap
# 2. all succeed
$lhs -f $rhs
$lhs -f ($rhs)
$lhs -f $($rhs)
$lhs -f @($rhs)
$rhs = "a" | SquareAndWrap
# 3. all succeed
$lhs -f $rhs
$lhs -f ($rhs)
$lhs -f $($rhs)
$lhs -f @($rhs)
$rhs = "a", "b" | SquareAndWrap
# 4. all succeed by coercing the inner array to the string "System.Object[]"
$lhs -f $rhs
$lhs -f ($rhs)
$lhs -f $($rhs)
$lhs -f @($rhs)
"a" | Square | % {
# 5. all fail
$lhs -f $_
$lhs -f ($_)
$lhs -f @($_)
$lhs -f $($_)
}
"a", "b" | Square | % {
# 6. all fail
$lhs -f $_
$lhs -f ($_)
$lhs -f @($_)
$lhs -f $($_)
}
"a" | Square | Wrap | % {
# 7. all fail
$lhs -f $_
$lhs -f ($_)
$lhs -f @($_)
$lhs -f $($_)
}
"a", "b" | Square | Wrap | % {
# 8. all fail
$lhs -f $_
$lhs -f ($_)
$lhs -f @($_)
$lhs -f $($_)
}
"a" | SquareAndWrap | % {
# 9. only @() and $() succeed
$lhs -f $_
$lhs -f ($_)
$lhs -f @($_)
$lhs -f $($_)
}
"a", "b" | SquareAndWrap | % {
# 10. only $() succeeds
$lhs -f $_
$lhs -f ($_)
$lhs -f @($_)
$lhs -f $($_)
}
Применяя те же шаблоны, которые мы видели в предыдущем вопросе, становится ясно, почему случаи, подобные №1 и №5, ведут себя по-разному: оператор конвейера сигнализирует механизму сценария развернуть другой уровень, а оператор присваивания - нет. Другими словами, все, что находится между двумя |, рассматривается как сгруппированное выражение, как если бы оно находилось внутри ().
# all of these output 2
("a" | Square).count # explicitly grouped
("a" | Square | measure).count # grouped by pipes
("a" | Square | Identity).count # pipe + ()
("a" | Square | Identity | measure).count # pipe + pipe
По той же причине случай №7 не является улучшением по сравнению с вариантом №5. Любая попытка добавить лишнюю оболочку будет немедленно отменена дополнительной трубкой. То же # 8 против # 6. Немного расстраивает, но до сих пор я полностью согласен.
Остающиеся вопросы:
- Почему дело №3 не постигнет судьба №4? $ rhs должен содержать вложенный массив (, ("a", "a")), но его внешний уровень разворачивается ... где-то ...
- Что происходит с различными операторами группировки в №9-10? Почему они ведут себя так беспорядочно и зачем они вообще нужны?
- Почему отказы в случае №10 не ухудшаются изящно, как в случае №4?