En Perl, las estructuras de datos simples son escalares, matrices y hashes, a los que accedemos directamente por nombre. Las referencias son escalares que contienen la dirección de otras estructuras de datos. Son necesarias para crear matrices anidadas (multidimensionales), hashes anidados y objetos complejos.
Ejemplo de uso de referencias:
my %hash = ( foo => 1, bar => 2 ); my $ref = \%hash; print $ref->{foo}; # 1 # Matriz de referencias a hashes my @array = ( { name => "Tom" }, { name => "Jerry" } ); print $array[1]{name}; # Jerry
Si no se utilizan referencias, no es posible crear, por ejemplo, una matriz multidimensional:
# Matriz multidimensional a través de referencias my $matrix = [ [1,2,3], [4,5,6] ]; print $matrix->[1][2]; # 6
Esto permite construir estructuras de datos complejas, pasarlas compactamente entre funciones e implementar patrones de OOP.
¿Se puede acceder a un elemento de una matriz (o hash) anidada sin utilizar referencias? Si es así, ¿cómo, y cuándo no funcionará?
A menudo se responde que no se puede, sin embargo, Perl a veces convierte "automáticamente" las estructuras. Pero sin referencias, las estructuras de anidamiento no funcionarán al crearse sobre la marcha o al pasarse como argumentos.
Ejemplo de acceso incorrecto y correcto:
# No funcionará así: my @arr = ( [1,2],[3,4] ); print $arr[0][1]; # 2 # Pero si se declara no como referencia, sino simplemente como matriz, entonces: my @matrix = ( [1,2], [3,4] ); print $matrix[1][0]; # 3
Historia
En un proyecto grande, se intentó pasar una referencia a una matriz sin el operador \, lo que hizo que la estructura interna se "descompusiera" como una matriz de escalares y llevó a una completa ruptura de la lógica.
Historia
Un desarrollador mezcló el acceso por referencia y sin referencia en el código, lo que resultó en la pérdida de datos en ciclos anidados foreach al trabajar con una matriz de referencias.
Historia
Al trabajar con una configuración anidada a través de un hash de referencias, se olvidó desreferenciar la referencia y se accedió como si fuera un hash, lo que provocó un error de tiempo de ejecución "Can't use string ("HASH(0x1234)") as a HASH" en producción.