2016-01-06 8 views
7

Perché il seguente codice:comportamento incoerente in materia di "Non è possibile utilizzare un valore indefinito come un riferimento ad array"

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}; 

Gettare l'errore "Can't use an undefined value as an ARRAY reference", mentre il codice seguente:

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}; 

non buttare via nulla, ma invece restituisce:

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

Entrambi hanno il merluzzo incriminato e in loro, ma solo uno sta lanciando l'errore.

possibile risposta:Perl's autovivification?

Sono sulla strada giusta? Grazie per il tuo contributo.

+1

Cosa stai cercando di fare? Il fatto che tu abbia disattivato gli avvisi per farlo dovrebbe essere davvero un buon campanello d'allarme che non è una buona idea. – Sobrique

+0

Sto solo cercando di capire cosa sta facendo Perl per lanciare l'errore in un punto e non in un altro per lo stesso bit di codice. Il primo blocco di codice proviene dal vecchio codice che genera l'errore e deve essere corretto, mentre il secondo blocco di codice è il più nuovo codice che sono preoccupato anche la correzione, ma credo che non lo sia poiché non genera l'errore che ho visto nel passato. – Morrowind789

risposta

9

Sì, quello che è successo nel secondo caso si chiama autovivificazione, ed è successo solo nel secondo caso perché l'autovivificazione avviene solo per lvalue [1].

Così

@{ $x } = $y; 

significa

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

ma

$y = @{ $x }; 

non significa

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

Ricordare che foreach alias la sua variabile loop su ogni elemento della lista su cui itera, quindi questi elementi vengono valutati come lvalue.

L'autovivificazione è documentata in perlref ed è possibile controllare l'autovivificazione tramite il pragma autovivification.


  1. Se il deferencing finale è seguito da un indicizzatore (ad esempio ->[] o ->{}), l'espressione di riferimento si è valutata come valore assegnabile anche se tutto indicizzata non è. Ciò significa che $y = $x->[0]; e $y = ${ $x }[0]; possono essere autovivificati $x anche se $y = @{ $x }; no.
+0

Questo è molto informativo. L'ultimo punto su come funziona foreaching aliasing della variabile di loop causandoci di essere in una situazione di lvalue chiarisce davvero le cose. La distinzione lvalue/valore dei valori è documentata da qualche parte in modo ufficiale? – Morrowind789

+0

@ Morrowind789 Viene menzionato brevemente in ['perldoc perlref'] (http://perldoc.perl.org/perlref.html # Using-References) al punto # 3 in "Uso dei riferimenti". Anche sotto la definizione di autovivificazione in [perlglossary] (http://perldoc.perl.org/perlglossary.html#autovivification). – ThisSuitIsBlackNot

+0

La documentazione per l'autovettura (in [perlref] (http://perldoc.perl.org/perlref.html)) fa: "Questo è uno dei casi che abbiamo menzionato in precedenza in cui i riferimenti potrebbero nascere quando in un contesto di lvalue [...] Questo processo è chiamato autovivificazione. " – ikegami

Problemi correlati