# array
C:> (1,2,3).count
3
C:> (1,2,3 | measure).count
3
# hashtable
C:> @{1=1; 2=2; 3=3}.count
3
C:> (@{1=1; 2=2; 3=3} | measure).count
1
# array returned from function
C:> function UnrollMe { $args }
C:> (UnrollMe a,b,c).count
3
C:> (UnrollMe a,b,c | measure).count
1
C:> (1,2,3).gettype() -eq (UnrollMe a,b,c).gettype()
True
The discrepancy with HashTables is fairly well known, although the official documentation only mentions it obliquely (via example).
The issue with functions, though, is news to me. I m kind of shocked it hasn t bitten me before now. Is there some guiding principle we scripters can follow? I know that when writing cmdlets in C# there s an overload of WriteObject where you can control enumeration explicitly, but AFAIK there s no such construct in the Posh language itself. As the final example shows, the Posh interpreter seems to believe there is no difference in the type of objects being piped. I suspect there may be some Object vs PSObject weirdness under the hood, but that s of little use when you re writing pure Posh and expect the script language to "just work."
/ EDIT /
Keith is correct to point out that in my example, I m passing in a single string[] argument rather than 3 string arguments. In other words, the reason Measure-Object says Count=1 is because it s seeing a single array-of-arrays whose first element is @("a", "b", "c"). Fair enough. This knowledge allows you to work around the issue in several ways:
# stick to single objects
C:> (UnrollMe a b c | measure).count
3
# rewrite the function to handle nesting
C:> function UnrollMe2 { $args[0] }
C:> (UnrollMe2 a,b,c | measure).count
3
# ditto
C:> function UnrollMe3 { $args | %{ $_ } }
C:> (UnrollMe3 a,b,c | measure).count
3
However, it doesn t explain everything...
# as seen earlier - if we re truly returning @( @("a","b","c") ) why not count=1?
C:> (UnrollMe a,b,c).count
3
# our theory must also explain these results:
C:> ((UnrollMe a,b,c) | measure).count
3
C:> ( @(@("a","b","c")) | measure).count
3
C:> ((UnrollMe a,b,c d) | measure).count
2
From what I can extrapolate there s another rule in play: if you have an array with exactly one element AND the parser is in expression mode, then the interpreter will "unwrap" said element. Any more subtleties I m missing?