2014-08-28 57 views
6

Açık bir şey eksik olabilir, ancak aşağıdaki Perl, neden grep, ancakveya başka bir genel başvuru yoluyla bir dizi başvuru oluşturduğu konusunda bir kayıp yaşıyorum? Ben Perl bu test ettikPerl neden grep ile boş bir dizi referansı yaratıyor?

print @$arr; # no output 
print ref $arr; # no output 
print scalar @$arr; # no output 
print ref $arr; # no output 
print sort @$arr; # no output 
print ref $arr; # no output 
print grep { 0 } @$arr; # no output 
print ref $arr; # ARRAY 

... muhtemelen bir şey bariz eksik veya belki de sadece şeylerden biri, ama beni Koçan ve herkes cevabını biliyordum merak ettim 5.8 ve 5.10 ve her ikisinde de aynı davranışı elde edin.

+0

Sanırım orada sahip olduğunuz şey Perl'de bir böcek. –

+0

... ama Perl'de asla bir böcek olmadığını düşündüm! –

+0

Skaler’in kesinlikle kod içermediğine dikkat edin. Sadece işlenişindeki bağlam işaretini değiştirir. Bu, fonksiyonların en sıra dışı özelliklerinden biridir, bu yüzden herhangi bir şeyin iyi bir örneği değildir! – ikegami

cevap

8

İlginç olan soru, neden diğerleriden biri değildir. Lvalue bağlamında dereferencing, undef ise işleneni otomatik olarak değiştirecektir.

$ perl -E'@$arr = "b"; say $arr // "[undef]"' 
ARRAY(0x335b558) 

değişkenleri her subs referansla geçirilir, böylece bunlar lvalue bağlamında değerlendirilmiştir.

$ perl -E'sub f { } f(@$arr); say $arr // "[undef]"' 
ARRAY(0x284e9f8)  

Ama perlfunc içinde "işlevleri" aslında operatörleri ve bu nedenle, kendi sözdizimi ve arama kuralları icat olsun. Perl, sort'un varsayılan karşılaştırma işlevini kullanırken işlenenlerini değiştirmeyeceğini bilir, bu nedenle bunları, lvalue bağlamında değerlendirmez. Bağımsız değişkenlerini lvalue bağlamda değerlendirilir böylece

$ perl -E'sort @$arr; say $arr // "[undef]"' 
[undef] 

grep takma adlar kendisine geçirilen her öğenin $_, bu yüzden onun argümanlar, (yani genellikle iyi bir fikir olmadığı halde) değiştirilebilir.

$ perl -E'@a = "a"; grep { $_ = uc($_) } @a; say @a' 
A 
+0

Aynı şey "for" ve "map" için de geçerli, çok net bir şekilde bir şeyler yapıyorsunuz. Kod bloğunun kendisi alakasız gibi gözüküyor, '$' nin takma adı yeterli görünüyor. – TLP

+0

İlginç, 'for' /' map' için düşünmedim, bazı ekstra testleri kaçırdığımı biliyordum. Bu yeni bir özellik inşa sırasında bir kontrol bizi yakaladı ve kesinlikle kafa karıştırıcı! –

İlgili konular