Comprender la diferencia de comportamiento entre el operador de asignación de perl y la combinación de operadores de asignación y lógicos-OR.
Hoy me sorprendí cuando me encontré con el siguiente comportamiento en perl:
sub f { die if %{ $[0] }; 42 }
my %h;
$h{x} ||= f(\%h); # morimos. $[0] hace referencia a un hash con clave ‘x’ durante la ejecución de f
En contraste, dada la misma configuración, la siguiente sentencia se comporta de manera diferente.
$h{x} = $h{x} || f(\%h); # $h{x} ahora es 42
¿Se documenta en algún lugar la posible diferencia entre la asignación lógica o y la combinación de asignación y lógica o?
Si esto se debe a la auto-vivificación, ¿es un error o una característica faltante en el módulo ‘autovivification’ que parece no ser capaz de detectar la auto-vivificación en esta construcción particular?
davy.ai
Como experto en informática especializado en Perl, operadores, evaluación y autovivificación, puedo explicar el comportamiento demostrado en los fragmentos de código anteriormente presentados. El operador
||=
es el operador de asignación de cortocircuito. Se asigna el valor derecho (rvalue) al valor izquierdo (lvalue) solo cuando el valor izquierdo es falso (es decir, no está definido, es 0 o una cadena vacía). En el primer fragmento de código, la expresión%{ $_[0] }
crea una referencia anónima a un hash desde el primer parámetro de la funciónf()
y comprueba si no está vacía. Dado que%h
es un hash vacío, la expresión devuelve falso y la declaracióndie
no se ejecuta. Por lo tanto, la subrutina devuelve el valor 42, pero el lado derecho del operador||=
nunca se evalúa y%h
permanece indefinido. Como resultado,h{x}
sigue siendo indefinido y el programa se bloquea con un error.El segundo fragmento de código muestra una forma alternativa de lograr el mismo propósito. Asigna
$h{x}
al resultado de la expresión$h{x} || f(\%h)
. Si$h{x}
es verdadero, es decir, ya está definido, evalúa a sí mismo y omite el segundo operando, que es la llamada a la subrutinaf()
. De lo contrario, llama af()
con%h
como su parámetro y asigna el valor resultante (42) a$h{x}
. En este caso,$h{x}
está definido y contiene 42, evitando que el programa se bloquee.Ambos comportamientos están documentados en la documentación de Perl, y no hay error ni característica faltante en la
autovivificación
, que solo se encarga de crear automáticamente estructuras de datos anidadas. Sin embargo, para evitar posibles comportamientos indefinidos durante la ejecución, es recomendable comprobar si una variable o estructura de datos está definida o no antes de usarla.