2009-12-01 15 views
9
# 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 

HashTables ile uyuşmazlık fairly well known olup, official documentation yalnızca bununla birlikte (örneğin) bunlardan bahseder.Powershell boru hattının bir koleksiyonu açıp açmayacağını belirleyen nedir?

fonksiyonları ile sorun olsa da, bana haber. Şimdiye kadar beni ısırmadığı için şok oldum. Yazarların izleyebileceği bazı rehber ilke var mı? Ben C# cmdlet'lerinizi yazarken açıkça numaralandırma kontrol edebilirsiniz bir overload of WriteObject var olduğunu biliyorum ama AFAIK Posh dilin kendisi böyle bir yapı yoktur. Son örnekte de görüldüğü gibi, Posh tercümanı, boru döşenen nesnelerin türünde hiçbir fark olmadığını düşünmektedir. Kaputun altında bazı Object vs PSObject tuhaflık olabileceğinden şüpheliyim, ama saf Posh yazdığınızda ve betik dilinin "sadece işe" geçmesini beklerken çok az kullanışlıdır.

/DÜZENLEME/

Keith benim örnekte ben 3 dize argümanları yerine tek dize [] argüman geçiyorum işaret etmek doğrudur. Diğer bir deyişle, bir neden Ölçü-Nesne bu ilk elemanı olan tek bir dizi-of-the dizileri gören çünkü Sayısı = 1 olduğunu söyler @ ("a", "b", "c"). Yeterince adil. ...

# 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 

Ancak, her şeyi açıklamıyor ben oyunda bir kural daha var tahmin kadarıyla

# 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 

: Bu bilgi, çeşitli yollarla soruna geçici izin verirse Tam olarak bir eleman ile bir dizi var VE çözümleyici expression mode, sonra yorumlayıcı söz konusu öğe "unwrap" olacaktır. Kaybolduğum başka incelikler var mı?

+0

WriteObject eşdeğeri, millerin nadiren kullanıldıkları yazım-çıkış cmdlet'idir (yankılanmaz). –

+0

Doğru, Write-Output, WriteObject (object, bool) gibi bir -EnumerateCollection parametresi içermiyor. –

+0

ile ilgili: http://stackoverflow.com/questions/28702588/in-what-conditions-does-powershell-unroll-items-in-the-pipeline/28707054#28707054 – alx9r

cevap

11

$ args açılarak. Fonksiyon parametrelerinin normalde bunları ayırmak için boşluk kullanılarak geçtiğini unutmayın. Eğer 1,2,3 geçmek zaman $ atanmaktadır üç sayı dizisi olan tek bir bağımsız değişken geçirerek bağımsız değişken [0]:

PS> function UnrollMe { $args } 
PS> UnrollMe 1 2 3 | measure 

Count : 3 

bir grup içinde sonuçları (bir dizi) vermesi ifade (veya örn.

PS> ((UnrollMe 1,2,3) | measure).Count 
3 

eşdeğerdir:

PS> ((1,2,3) | measure).Count 
3 

btw değil $()) altta bulunan nesne [] 1,2,3 UnrollMe tarafından döndürülen içeren açıyor yuvarlayarak açmaya tekrar uygun hale getirir sadece bir öğe ile bir dizi için geçerlidir. Bir dizi olursa olsun uygulamak kaç kez hiçbir etkisi olmaz zaten bir şey üzerinde bir dizi alt ifade (@()) kullanarak

PS> ((1,2),3) | %{$_.GetType().Name} 
Object[] 
Int32 

. :-) Açılıştan kaçınmak istiyorsanız, virgül operatörünü kullanın, çünkü her zaman açılacak başka bir dış dizi oluşturun. Bunu yürütmek zaman Nihayet

PS> (,(1,2,3) | measure).Count 
1 

: Gerçekten unrolling engellemez bu senaryoda, sadece bunun yerine orijinal dizi örn unrolled alır bir dış "sarıcı" dizi tanıtarak unrolling geçici olduğunu unutmayın :

PS> (UnrollMe a,b,c d) | %{$_.GetType().Name} 
Object[] 
String 

Sen UnrollMe iki öğe döndüren görebilirsiniz (a, b, c) bir sayısal olarak bir dizi ve d olarak. Bu iki öğe, sonuç sayısı 2 olan boru hattından ayrı olarak gönderilir.

+0

İyi çağrı. Açıklığa kavuşturmak için: örneğimde, $ args sadece bir dizi değil, diziler dizisidir. İlk ve tek elemanı @ 'dır (1,2,3). –

+0

Hmm, daha fazla yansımada bu, cevap verdiğinden daha fazla soru ortaya çıkarır. –

+0

>> Sonuçların (dizi) bir grup ifadesinde (veya alt ifadenin ör. $()) Verilmesi, tekrar açılmasını sağlar. //// Mükemmel özet, teşekkürler. –

1

boru hattı boyunca iletilir nasıl Ölçü-Nesne çalıştığını ve nasıl nesneleri ile ilgili bir şey var gibi görünüyor.

Eğer

1,2,3 | measure 

söylerken boru hattı üzerine geçirilen 3 Int32 nesneleri, daha sonra her boru hattındaki görür nesne sayar nesneyi ölçmek olsun. Eğer "önüne sermek" Ne zaman burada gösterildiği gibi

sizin işlevini kullanarak, sen tedbir nesne sayımları 1 olarak, bu dizide nesneler arasında dolaşmak için hiçbir girişimde bulunmaz boru hattı üzerine geçirilen tek dizi nesnesi olsun:

PS C:\> (measure -input 1,2,3).count 
1 

olası iş çevresinde "Re-roll" foreach kullanarak boru hattı üzerine dizidir:

PS C:\> (UnrollMe 1,2,3 | %{$_} | measure).count 
3