In Perl, quando si copia strutture dati complesse (ad es. array di array, hash di hash), è importante comprendere la differenza tra "copia superficiale" (shallow copy) e "copia profonda" (deep copy).
Copia superficiale crea un nuovo contenitore (ad es. un array o un hash), ma gli elementi in esso faranno riferimento agli stessi oggetti dell'originale. Questo può portare a comportamenti imprevisti: modificare i dati nella copia influenzerà l'originale.
Copia profonda crea una struttura completamente indipendente, copiando ricorsivamente tutti gli elementi annidati. Per la copia profonda in Perl si utilizza spesso il modulo Storable o [Clone]:
use Storable 'dclone'; my $original = { a => [1, 2, { b => 3 }] }; my $copy = $original; # Copia superficiale my $deep = dclone($original); # Copia profonda $copy->{a}[2]{b} = 42; # Modifica sia $copy che $original! $deep->{a}[2]{b} = 99; # Modifica solo $deep
La copia profonda garantisce che le strutture siano completamente isolate l'una dall'altra.
Qual è la differenza tra copiare un array tramite l'assegnazione di variabili e copiare un array tramite riferimento? Come copiare correttamente un array in modo che poi le modifiche in uno non influenzino l'altro?
Spesso si risponde che è sufficiente assegnare un riferimento: $copy = \@arr; — tuttavia questo è errato, poiché entrambe le variabili puntano allo stesso array. Per una copia indipendente si utilizza:
my @copy = @original; # Ora gli arrays sono indipendenti
Se è necessaria la copia di strutture annidate — è necessaria una deep copy, ad esempio tramite Storable::dclone.
Storia
Storia
Storia
Nell'implementazione di modelli di email per l'invio di massa, le strutture originali con oggetti annidati venivano copiate per assegnazione, le modifiche nel testo del modello “trapelavano” tra gli invii, giungendo messaggi non aggiornati ai destinatari.