2010-12-08 13 views
17

Ben bir dizi bu sözdizimini kullanmaya çalıştıNeden == dizilerle çalışmıyor?

$x ||= 1; 

gibi değişkenler için varsayılan değerler sağlamak için ||= operatörü kullanan ancak bir sözdizimi hatası var:

@array||= 1..3; 
Can't modify array dereference in logical or assignment (||=) ... 

Ne anlama geliyor ve nasıl varsayılan değerler içeren diziler sağlamalı mıyım? Çünkü || bir skalar işleç olduğundan

cevap

18

. @array||= 1..3; çalıştıysa, skaler bağlamda 1..3 değerini değerlendirirsiniz, bu sizin istediğiniz gibi değildir. Ayrıca skaler bağlamdaki diziyi de değerlendirir (skaler bağlamdaki boş bir dizi yanlış olduğundan, tamam), scalar(@array)'a atayamazsınız.

varsayılan bir değer, kullanımını atamak için:

@array = 1..3 unless @array; 

Ama bir başlatıldı olmamıştı dizisi ve boş liste atanmıştır arasındaki farkı anlatmak için bir yolu yoktur unutmayın. undef ve boş dize arasında ayrım yapabileceğiniz bir skaler gibi değil (ancak ||= bunların arasında ayrım yapmaz).

eugene y, bu konuda daha ayrıntılı bilgi veren this perl.perl5.porters message (resmi Perl geliştiricilerinin posta listesi) buldu.

+5

'||' değil buna işlenen bıraktı üzerinde skaler bağlamını empoze yapar rağmen bir sayıl operatörü. Perlop'tan: "Skaler veya liste içeriği değerlendirilirse sağ işlenene doğru ilerler." "perl -MData :: Dump = dump -e" @a = 0 || (1 .. 3); dökümü (\ @ a) "baskı" [1, 2, 3] ' –

+0

*" yolu yoktur hiçbir zaman başlatılmamış bir dizi ile boş listeye atanmış bir dizi arasındaki farkı söyleyin. * Farkı söylemek sadece imkansız değildir: * fark yoktur *. – Borodin

+0

Bu cevap tamamen yanlış. 'perl -le'print 0 || 1..3 '' 123 'yazdırır, baskı skalar (1..3) gibi boş bir satır yazmaz. – ikegami

16

Bu page imho, iyi bir açıklaması var:

op= can occur between any two expressions, not just a var and an expression, but the left one must be an lvalue in scalar context.

Since @x ||= 42 is equivalent to scalar(@x) = @x || 42 , and you aren't allowed to use scalar(@x) as an lvalue, you get an error.