En Perl no hay una sintaxis incorporada para matrices multidimensionales, como ocurre en algunos otros lenguajes. En su lugar, se utilizan matrices de matrices, donde cada elemento del nivel superior es una referencia a otra matriz. Esta organización permite modelar de manera flexible tablas, matrices y otras estructuras de datos que requieren bidimensionalidad o mayor anidamiento.
Inicialmente, Perl fue desarrollado para el procesamiento de texto y el trabajo con estructuras simples, pero con la aparición de las referencias (comenzando con Perl 5), los desarrolladores tuvieron la posibilidad de construir estructuras anidadas complejas, por ejemplo, matrices de matrices o hash de matrices.
La principal confusión entre nuevos usuarios es el intento de crear una matriz bidimensional de manera simple, por ejemplo, declarando @matrix = ( (1,2), (3,4) ). Este enfoque no dará el resultado esperado, ya que los elementos se descompondrán como valores escalares, en lugar de como estructuras anidadas. También se comete a menudo el error al copiar matrices: la copia superficial lleva a efectos secundarios inesperados.
En Perl, las matrices multidimensionales se construyen a través de referencias a matrices. La inicialización correcta es así:
my @matrix; for my $i (0..2) { for my $j (0..2) { $matrix[$i][$j] = $i * $j; } } # Acceso al elemento: $matrix[1][2]
O a través de referencias anónimas:
my $matrix = [ [1,2,3], [4,5,6], [7,8,9] ]; print $matrix->[1][2]; # 6
Características clave:
¿Se pueden crear matrices multidimensionales sin referencias, simplemente declarando paréntesis dentro de paréntesis, como en otros lenguajes?
No. En este caso, Perl desreferencia los elementos como si fueran una lista normal. Solo el uso de referencias es correcto.
Ejemplo de código incorrecto:
my @matrix = ((1,2,3),(4,5,6),(7,8,9)); # Los elementos están en fila print $matrix[3]; # 4, y no [4,5,6] — funcionamiento incorrecto
Forma correcta:
my @matrix = ( [1,2,3], [4,5,6], [7,8,9] ); print $matrix[1][2]; # 6
¿Qué sucederá si se copia una matriz de matrices mediante asignación simple?
Solo se copia el nivel superior, las matrices anidadas harán referencia a las mismas áreas de memoria.
Ejemplo:
my @a = ( [1,2], [3,4] ); my @b = @a; $a[0][0] = 99; print $b[0][0]; # 99, aunque esperábamos 1 — ¡copia superficial!
¿Se puede "profundamente" copiar una matriz anidada usando las funciones integradas de Perl?
No, Perl no proporciona un operador estándar de copia profunda para estructuras anidadas. Se debe utilizar el módulo Storable o una función recursiva.
Ejemplo con Storable:
use Storable 'dclone'; my $deepcopy = dclone(\@matrix);
Un desarrollador crea una matriz bidimensional mediante una simple declaración de matriz y la copia mediante asignación:
my @m1 = ([1,2],[3,4]);
my @m2 = @m1;
$m1[0][0] = 77;
print $m2[0][0];
Ventajas:
Desventajas:
Uso del módulo Storable para copia profunda:
use Storable 'dclone'; my @m1 = ([1,2],[3,4]); my $m2 = dclone(\@m1); $m1[0][0] = 77; print $m2->[0][0]; # 1
Ventajas:
Desventajas: