In Perl, per default la copia di strutture referenziali (come array di array o hash di hash) viene eseguita superficialmente: si copiano solo i riferimenti stessi e non i contenuti annidati. Storicamente, questo portava spesso a effetti imprevisti: la modifica della struttura interna in una copia si riflette nelle altre. Soluzione: utilizzare metodi e moduli specializzati per la clonazione profonda, al fine di creare una struttura autonoma con elementi annidati indipendenti.
Esempio di codice (utilizzando Storable):
use Storable 'dclone'; my $original = { a => [1, 2, { x => 10 }] }; my $copy = dclone($original); $copy->{a}[2]{x} = 20; print $original->{a}[2]{x}; # 10
Caratteristiche chiave:
L’operatore “=” ($copy = $ref) funziona per la copia profonda?
No, l’operatore “=” copia solo il riferimento stesso. Dopo tale assegnazione, qualsiasi modifica a $copy si riflette anche in $ref.
È possibile utilizzare la funzione Data::Dumper per la copia profonda di una struttura?
Data::Dumper è uno strumento per il debug e la serializzazione in stringa, non è destinato a ripristinare la struttura dei dati in memoria. Per la conversione inversa è necessaria una valutazione (eval), il che è pericoloso e non consigliato per motivi di sicurezza e prestazioni.
Funziona sempre dclone correttamente con oggetti (riferimenti benedetti)?
Storable::dclone clona oggetti, ma solo se la classe non sovrascrive i metodi di serializzazione o non contiene oggetti non standard (come descrittori di file o riferimenti forti a risorse esterne). Per oggetti complessi è necessario implementare i metodi STORABLE_freeze e STORABLE_thaw.
Un array di array viene duplicato con l'operatore =, vengono apportate modifiche a una delle strutture annidate — tutte le copie mostrano le stesse modifiche.
Vantaggi:
Svantaggi:
Si utilizza Storable::dclone o Clone::PP, tutte le strutture annidate sono indipendenti.
Vantaggi:
Svantaggi: