Note that there are some explanatory texts on larger screens.

plurals
  1. POHow *exactly* does the RHS of PowerShell's -f operator work?
    text
    copied!<p><a href="https://stackoverflow.com/questions/1827862/what-determines-whether-the-powershell-pipeline-will-unroll-a-collection">Last time I got confused</a> by the way <a href="http://en.wikipedia.org/wiki/Windows_PowerShell" rel="nofollow noreferrer">PowerShell</a> eagerly unrolls collections, Keith summarized its heuristic like so:</p> <blockquote> <p>Putting the results (an array) within a grouping expression (or subexpression e.g. $()) makes it eligible again for unrolling.</p> </blockquote> <p>I've taken that advice to heart, but still find myself unable to explain a few esoterica. In particular, the Format operator doesn't seem to play by the rules.</p> <pre><code>$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 $($_) } </code></pre> <p>Applying the same patterns we saw in the previous question, it's clear why cases like #1 and #5 behave different: the pipeline operator signals the script engine to unroll another level, while the assignment operator does not. Put another way, everything that lies between two |'s is treated as a grouped expression, just as if it were inside ()'s.</p> <pre><code># 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 </code></pre> <p>For the same reason, case #7 is no improvement over #5. Any attempt to add an extra <strong>Wrap</strong> will be immediately subverted by the extra pipe. Ditto #8 vs #6. A little frustrating, but I'm totally on board up to this point. </p> <p>Remaining questions:</p> <ul> <li>Why doesn't case #3 suffer the same fate as #4? <strong>$rhs</strong> should hold the nested array <strong>(,("a", "a"))</strong> but its outer level is getting unrolled...somewhere...</li> <li>What's going on with the various grouping operators in #9-10? Why do they behave so erratically, and why are they needed at all?</li> <li>Why don't the failures in case #10 degrade gracefully like #4 does?</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload