En Perl, el resultado de una asignación (y, por ende, trabajar con arreglos y hashes) depende del contexto.
my @arr = (10, 20, 30); my $count = @arr; # $count == 3 my ($first, $second) = @arr; # $first == 10, $second == 20
Para hashes:
my %h = (a=>1, b=>2, c=>3); my $size = %h; # $size == 3 en versiones modernas de Perl, ¡pero antes no era así!
¡Cuidado con asignar un enlace al arreglo en lugar de copiar el contenido!
¿Cuál es la diferencia entre asignar un arreglo a una referencia y copiar el contenido del arreglo?
Respuesta:
my @a = (1,2,3); my $ref = \@a; # $ref es una referencia al arreglo, los cambios a través de $ref se ven en @a my @b = @a; # @b es un nuevo arreglo, los cambios en @b no afectan a @a # Comparar: push @$ref, 4; # @a ahora es (1,2,3,4) push @b, 5; # @a permanece (1,2,3,4); @b es (1,2,3,5)
Historia 1
En el proyecto, se pasaba un arreglo a una subrutina a través de una referencia, sin entender que era exactamente una referencia: la función lo modificaba en el punto de llamada. Aparecieron errores; en el código que llamaba, la estructura de datos ya había sido "dañada". Esperaban una copia, obtuvieron un alias.
Historia 2
Un ingeniero pensaba que la asignación escalar de
%hdevolvería el número real de pares. Resultó que en versiones antiguas de Perl este comportamiento era diferente: se devolvía el número de ranuras/buckets, ¡y no la longitud! Como resultado, a veces devolvía no 3, sino otro número, que rompía la estadística.
Historia 3
En un gran sistema ETL, los arreglos se copiaban a través de referencias, y luego inesperadamente sobrescribían datos entre sí, porque todos trabajaban con el mismo arreglo y no con copias independientes. Diagnosticar el error tomó varios días.