# 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
La discrepancia con HashTables es fairly well known, aunque el official documentation solo lo menciona oblicuamente (mediante ejemplo).¿Qué determina si la tubería de Powershell desenrollará una colección?
El problema con las funciones, sin embargo, es nuevo para mí. Estoy sorprendido de que no me haya mordido antes. ¿Hay algún principio rector que podamos seguir los scripters? Sé que al escribir cmdlets en C# hay un overload of WriteObject donde puedes controlar la enumeración explícitamente, pero AFAIK no existe tal construcción en el lenguaje Posh. Como muestra el ejemplo final, el intérprete Posh parece creer que no hay diferencia en el tipo de objetos que se canalizan. Sospecho que puede haber alguna rareza de Object vs PSObject bajo el capó, pero eso es de poca utilidad cuando estás escribiendo Posh puro y esperas que el lenguaje de script "simplemente funcione".
/editar/
Keith es correcto señalar que en mi ejemplo, yo estoy de paso en un solo argumento string [] en lugar de 3 argumentos de cadena. En otras palabras, la razón por la cual Measure-Object dice Count = 1 es porque está viendo una única matriz de matrices cuyo primer elemento es @ ("a", "b", "c"). Lo suficientemente justo. Este conocimiento le permite trabajar en torno al tema de varias maneras:
# 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
Sin embargo, no explica todo ...
# 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
De lo que puedo extrapolar hay otra regla de juego: si usted tiene una matriz con exactamente un elemento Y el analizador está en expression mode, entonces el intérprete "desenrollará" dicho elemento. ¿Alguna más sutileza que me falta?
El equivalente de WriteObject es el cmdlet Write-Output (alias a echo) que las personas rara vez utilizan porque los valores se envían implícitamente a la corriente stdout. –
Es cierto, aunque Write-Output no tiene un parámetro -EnumerateCollection como WriteObject (object, bool). –
relacionado: http://stackoverflow.com/questions/28702588/in-what-conditions-does-powershell-unroll-items-in-the-pipeline/28707054#28707054 – alx9r