está probando un valor indefinido para el cero numérico. ¡Por supuesto que obtienes un verdadero resultado! ¿Que estabas esperando?
También debería recibir una advertencia en use warnings
. ¿Por qué no?
Si no inicia un programa con:
use v5.12; # or whatever it is you are using
use strict;
use warnings;
que realmente no debería molestarse. :)
EDITAR
Nota: Sólo estoy aclarando la corrección, porque las líneas de comentarios no son buenos para eso. Realmente no podría preocuparme un poco menos por los puntos de reputación. Solo quiero que la gente lo entienda.
Incluso bajo el módulo CPAN autovivification
, nada cambia. Testigo:
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.";
}
Cuando se ejecuta, que dice:
$ perl /tmp/demo
Use of uninitialized value in numeric eq (==) at /tmp/demo line 10.
yup, that was zero.
La prueba es el operador ==
. Su RHS es 0
.Su LHS es undef
independientemente de la autovibición. Dado que undef
es numéricamente 0
, eso significa que tanto LHS como RHS contienen 0
, que el ==
identifica correctamente como que tiene el mismo número.
Autovivificación no es el problema aquí, ya que se observa correctamente cuando escribe que "Esto no es una pregunta específica multidimensional de hash." Todo lo que importa es lo que pasa a ==
. Y undef
es numéricamente 0
.
Puede detener autoviv si realmente, realmente desea - mediante el uso del pragma CPAN. Pero nunca podrás cambiar lo que sucede aquí al suprimir autoviv. Eso muestra que no es un asunto de autoviv, solo un undef
.
Ahora, usted obtendrá "extra" claves cuando haga esto, ya que el valor lvalue indefinido se completará en el camino a través de la cadena de referencia. Estos son todos iguales neccesarily:
$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
Cada vez que un DEREF lvaluable undef
en Perl, que la ubicación de almacenamiento siempre se llena con el tipo adecuado de referencia a un referente en el anonimato recién asignado del tipo adecuado. En resumen, autovivs.
Y que se puede detener suprimiendo o bien dejando de lado el autoviv. Sin embargo, negar el autoviv no es lo mismo que eludirlo, porque solo cambias qué tipo de cosas se devuelven. La evaluación general todavía se evalúa por completo: no hay cortocircuitos automáticos simplemente porque suprime autoviv. Eso es porque autoviv no es el problema (y si no estuviera allí, estarías realmente molesto: confía en mí).
Si quiere un cortocircuito, tiene que escribirlo usted mismo. Parece que nunca necesito hacerlo. En Perl, eso es. Por otro lado, los programadores de C son bastante acostumbrado a escribir
if (p && p->whatever) { ... }
Y por lo que pueden hacer eso, también, si así lo desea. Sin embargo, es bastante raro en mi propia experiencia. Casi tiene que doblarse en Perl para que eso marque la diferencia, ya que es bastante fácil organizar su código y no para cambiar la forma en que actúa si hay niveles vacíos.
Awesome !! Tu ejemplo solucionó mi problema y tu consejo me llevó a http://www.perlmonks.org/?node=Autovivification, ¡ahora lo sé! ¡Gracias! – Analog
@Analog: Pero esa no es la respuesta correcta. La respuesta correcta es no aplicar pruebas numéricas de igualdad contra valores indefinidos. – tchrist
@tchrist: Entonces, cada afirmación que hice era 100% correcta, y resolví el problema del OP, pero como violé tu sentido personal de estilo, mi respuesta fue rechazada. ¿Lo tengo bien? ¡De buen tono! – Nemo