# 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 discrepanza con HashTables è fairly well known, sebbene lo official documentation lo menzioni solo in modo obliquo (tramite l'esempio).Che cosa determina se la pipeline di PowerShell dispiegherà una raccolta?
Il problema con le funzioni, tuttavia, è una novità per me. Sono un po 'scioccato che non mi abbia morso prima d'ora. C'è qualche principio guida che gli sceneggiatori possono seguire? So che scrivendo cmdlet in C# c'è un overload of WriteObject in cui è possibile controllare esplicitamente l'enumerazione, ma AFAIK non esiste un tale costrutto nel linguaggio Posh stesso. Come mostra l'esempio finale, l'interprete di Posh sembra credere che non ci siano differenze nel tipo di oggetti che vengono condotti. Ho il sospetto che ci possa essere qualche stranezza Object vs PSObject sotto il cofano, ma questo è di scarso utilizzo quando si scrive puro Posh e si aspetta che il linguaggio dello script "funzioni solo".
/EDIT/
Keith è corretto sottolineare che nel mio esempio, sto passando in una singola stringa argomento [], piuttosto che 3 argomenti stringa. In altre parole, la ragione per cui Measure-Object dice Count = 1 è perché sta vedendo un singolo array di array il cui primo elemento è @ ("a", "b", "c"). Giusto. Questa conoscenza permette di lavorare intorno al problema in vari modi:
# 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
Tuttavia, non spiega tutto ...
# 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
Da quello che posso estrapolare c'è un'altra regola in gioco: se si dispone di un array con esattamente un elemento E il parser è in expression mode, quindi l'interprete "scribaccherà" detto elemento. Altre sottigliezze che mi mancano?
L'equivalente di WriteObject è il cmdlet Write-Output (con alias di echo) che gli utenti utilizzano raramente poiché i valori vengono emessi in modo implicito nel flusso stdout. –
È vero, sebbene Write-Output non abbia un parametro -EnumerateCollection come WriteObject (oggetto, bool). –
correlati: http://stackoverflow.com/questions/28702588/in-what-conditions-does-powershell-unroll-items-in-the-pipeline/28707054#28707054 – alx9r