si esegue il test un valore indefinito per lo zero numerico. Certo che ottieni un risultato vero! Cosa ti aspettavi?
È inoltre necessario ricevere un avviso in use warnings
. Perché non l'hai fatto?
Se non si avvia un programma con:
use v5.12; # or whatever it is you are using
use strict;
use warnings;
davvero non dovrebbe nemmeno. :)
EDIT
NB: Sto solo chiarendo la correttezza, perché le righe di commento non sono buone per questo. Non potevo davvero preoccuparmi di lamentarsi di meno dei punti reputazione. Voglio solo che la gente capisca.
Anche sotto il modulo CPAN autovivification
, non cambia nulla. Testimone:
use v5.10;
use strict;
use warnings;
no autovivification;
my %md_hash =();
$md_hash{top}{primary}{secondary} = 0;
if ($md_hash{top}{foobar}{secondary} == 0) {
say "yup, that was zero.";
}
Quando eseguito, che dice:
$ perl /tmp/demo
Use of uninitialized value in numeric eq (==) at /tmp/demo line 10.
yup, that was zero.
Il test è l'operatore ==
. Il suo RHS è 0
.Il suo LHS è undef
indipendentemente dall'autovettura. Poiché undef
è numericamente 0
, ciò significa che sia LHS che RHS contengono 0
, che lo ==
identifica correttamente come contenente lo stesso numero.
L'autovivificazione non è il problema qui, come giustamente osserva ysth quando scrive che "Questa non è una domanda specifica di hash multidimensionale". Tutto ciò che conta è ciò che si passa a ==
. E undef
è numericamente 0
.
È possibile interrompere autoviv se lo si desidera, davvero - utilizzando il pranma CPAN. Ma non riuscirai mai a cambiare ciò che accade qui sopprimendo autoviv. Ciò dimostra che non è affatto una questione di autoviv, solo uno undef
.
Ora, si ottenere i tasti "extra" quando si esegue questa operazione, poiché il valore non definito verrà compilato nel percorso attraverso la catena di deferimento. Questi sono neccesarily tutti uguali:
$md_hash{top}{foobar}{secondary} # implicit arrow for infix deref
$md_hash{top}->{foobar}->{secondary} # explicit arrow for infix deref
${ ${ $md_hash{top} }{foobar} }{secondary} # explicit prefix deref
Ogni volta che si Deref un lvaluable undef
in Perl, che posizione di archiviazione sempre si riempie con il corretto tipo di riferimento ad un referente anonima appena allocato del tipo corretto. In breve, ha un'autovettura.
E che si può interrompere eliminando o spostando l'autoviv. Tuttavia, negare l'autoviv non equivale a sottrarlo, perché basta cambiare il tipo di oggetto che viene restituito. La spesa complessiva è ancora completamente valutata: non c'è il cortocircuito automatico solo perché si sopprime l'autoviv. Questo perché autoviv non è il problema (e se non fosse lì, saresti davvero seccato: credimi).
Se si desidera cortocircuitare, è necessario scriverlo da soli. Non ho mai bisogno di me stesso. In Perl, cioè. D'altra parte, i programmatori C sono abbastanza abituato a scrivere
if (p && p->whatever) { ... }
e così si può fare anche quello, se si vuole. Tuttavia, è abbastanza raro nella mia esperienza personale. Devi quasi piegarti in modo errato in Perl per fare sempre la differenza, dato che è abbastanza facile organizzare il tuo codice non per cambiare il modo in cui agisce se ci sono livelli vuoti.
Fantastico !! Il tuo esempio ha risolto il mio problema e il tuo consiglio mi ha portato a http://www.perlmonks.org/?node=Autovivification, ora lo so !! Grazie! – Analog
@Analog: Ma questa non è la risposta giusta. La risposta corretta non è applicare test di uguaglianza numerica rispetto a valori non definiti. – tchrist
@tchrist: Quindi ogni affermazione che ho fatto è stata corretta al 100%, e ho risolto il problema dell'OP, ma poiché ho violato il tuo personale senso dello stile hai ridimensionato la mia risposta. Ho capito bene? Classy! – Nemo