En Perl, para realizar una copia profunda de estructuras anidadas (por ejemplo, hashes de arrays, arrays de hashes) no se puede utilizar la asignación simple o las funciones estándar (@b = @a, %b = %a, $clone = $orig). Estas operaciones solo crean una copia superficial: los objetos anidados aún se refieren a las mismas áreas de memoria.
Para la copia profunda, se utilizan:
Storable:use Storable 'dclone'; my $deep_copy = dclone($structure);
Clone: uso similar.Es importante recordar: se copian todos los niveles de anidación, incluidas las referencias dentro de la estructura.
¿Qué sucede al realizar una asignación simple de una estructura de datos compleja: se copian los elementos anidados?
Respuesta: No, solo se copia el nivel superior. Los arrays y hashes internos siguen siendo compartidos entre el original y la copia.
my $orig = { a => [1,2,3], b => { x => 7 } }; my $copy = $orig; $copy->{a}[0] = 99; # $orig->{a}[0] — ¡también se convertirá en 99!
Solo el uso de clonación profunda proporcionará una copia completamente independiente.
Historia 1
En una aplicación REST API, se clonaron las solicitudes para diferentes clientes mediante una simple asignación de referencia. Como resultado, los cambios en la respuesta de un cliente se reflejaban instantáneamente en todos los demás, porque todos trabajaban con la misma estructura de datos anidada.
Historia 2
Al agregar datos de una estructura compleja de arrays, se utilizó la copia a través de push (push @new, @old), olvidando los niveles anidados. Un cambio accidental en un hash anidado rompió los datos de todos los agregados — el error no pudo ser identificado durante mucho tiempo.
Historia 3
Para el procesamiento de registros, se duplicó la estructura en un script a través de Clone, pero no se tomaron en cuenta los campos "mágicos" especiales de los objetos — por lo tanto, se perdieron los métodos/atributos necesarios. Como resultado, la funcionalidad era inválida, y el error solo se reprodujo en producción.