2016-01-06 24 views
7

Neden Aşağıdaki kod yok "bir ARRAY referans olarak tanımlanmamış bir değer kullanılamaz":Tutarsız davranışlar

use strict; 
use warnings; 
no warnings 'uninitialized'; 

use Data::Dumper; 

my $user; 
foreach my $enterprise(@{$user->{ENTERPRISES}}) { 
    print qq{Enterprise:}, $enterprise; 
} 
print Dumper($user), qq{Done!\n}; 
:

use strict; 
use warnings; 
no warnings 'uninitialized'; 

use Data::Dumper; 

my $user; 
my @data = @{$user->{ENTERPRISE}}; # Error on this line 
print Dumper($user), qq{Done!\n}; 

, hatayı "Can't use an undefined value as an ARRAY reference" atın aşağıdaki kodla ederken

şey atmak yok mu, bunun yerine döndürür:

$VAR1 = { 
      'ENTERPRISES' => [] 
     }; 
Done! 

Hem kusurlu morina var İçlerinde e, ancak sadece bir hata atıyor.

Olası Cevap: Burada doğru yoldaPerl's autovivification?

Am I? Girdiniz için teşekkürler.

+1

Aslında ne yapmaya çalışıyorsunuz? Bunu yapmak için uyarıları kapatmış olmanız, iyi bir fikir olmaması için gerçekten iyi bir uyarı zili olmalıdır. – Sobrique

+0

Sadece Perl'in hatayı bir yere atmak için ne yaptığını anlamaya çalışıyorum, aynı kod için başka bir yerde değil. İlk kod bloğu, hatayı atan ve düzeltilmesi gereken eski koddan, ikinci kod bloğunun ise daha yeni bir kod olması gerektiğinden endişeleniyorum, ama sanırım hata bulmuyormuş gibi görünmüyor geçmişte. – Morrowind789

cevap

9

Evet, ikinci durumda olana otomatikleştirme denir ve yalnızca ikinci durumda gerçekleşir çünkü otolık giderme yalnızca [1] için geçerlidir.

Yani

@{ $x } = $y; 

anlamına gelmez

@{ $x //= [] } = $y; 

ama

$y = @{ $x }; 

demektir

$y = @{ $x //= [] }; 

Foreach'ın döngü değişkenini, üzerinde yinelediği listenin her bir öğesine taklit ettiğini unutmayın, bu nedenle bu elemanlar lvalues ​​olarak değerlendirilir.

Otomatikleştirme, perlref numaralı belgede belgelenmiştir ve autovivification pragma aracılığıyla otomatik olarak denetimi denetleyebilirsiniz. Nihai deferencing bir indeksleme (örneğin ->[] veya ->{}) takip edilirse


  1. referans ifadesi kendisini dizinlenmiş bütün olmasa bile bir lvalue olarak değerlendirilir. Bu, $y = @{ $x };, $y = @{ $x }; olmasa bileve $y = ${ $x }[0];'un $x'u otomatik olarak kapatabileceği anlamına gelir.
+0

Bu çok bilgilendirici. Foreach'in nasıl bir değişkenlik durumunda olmasına neden olan döngü değişkenini taklit ederek nasıl çalıştığına dair son noktanız gerçekten bir şeyleri temizler. Lvalue/rvalue unvanı resmi olarak bir yerde belgelendi mi? – Morrowind789

+0

@ Morrowind789 Kısaca ['perldoc perlref'] 'den bahsedilmiştir (http://perldoc.perl.org/perlref.html # Using-References) "Referansların Kullanılması" altındaki # 3 numaralı noktada. Ayrıca [perlglossary] 'de otomatikleştirme tanımlaması altında (http://perldoc.perl.org/perlglossary.html#autovivification). – ThisSuitIsBlackNot

+0

Otomasyona ilişkin belgeler ([perlref] içinde (http://perldoc.perl.org/perlref.html)) şunu yapar: "Daha önce değindiğimiz referanslardan biri, bir referansın bir bağlamda var olduğunda ortaya çıkabileceği durumlardan biridir. [...] Bu işlem otomatikleştirme olarak adlandırılır. " – ikegami