In Perl kan je voor het maken van een diepe kopie van geneste structuren (zoals array hashes, hashes van arrays) geen eenvoudige toewijzing of standaardfuncties gebruiken (@b = @a, %b = %a, $clone = $orig). Dergelijke operaties maken alleen een oppervlakkige kopie: geneste objecten verwijzen nog steeds naar dezelfde geheugengebieden.
Voor het maken van een diepe kopie gebruiken we:
Storable:use Storable 'dclone'; my $deep_copy = dclone($structure);
Clone: vergelijkbare toepassing.Het is belangrijk om te onthouden: alle niveaus van genestheid worden gekopieerd, inclusief verwijzingen binnen de structuur.
Wat gebeurt er bij eenvoudige toewijzing van een complexe datastructuur: worden geneste elementen gekopieerd?
Antwoord: Nee, alleen het bovenste niveau wordt gekopieerd. Interne arrays en hashes blijven gedeeld tussen het origineel en de kopie.
my $orig = { a => [1,2,3], b => { x => 7 } }; my $copy = $orig; $copy->{a}[0] = 99; # $orig->{a}[0] — zal ook 99 worden!
Alleen het gebruik van diepe kloning zal een volledig onafhankelijke kopie geven.
Verhaal 1
In een REST API-toepassing werden verzoeken voor verschillende klanten gekloond door middel van eenvoudige toewijzing van verwijzingen. Hierdoor werden wijzigingen in het antwoord van één klant onmiddellijk weerspiegeld bij alle anderen - omdat ze allemaal met dezelfde geneste datastructuur werkten.
Verhaal 2
Bij het aggregeren van gegevens uit een complexe arraystructuur werd een kopie gemaakt via push (push @new, @old), waarbij de geneste niveaus werden vergeten. Een toevallig gebruik van een geneste hash beschadigde de gegevens van alle aggregaten - de bug kon lange tijd niet worden gevonden.
Verhaal 3
Voor het verwerken van logs werd de structuur in een script gedupliceerd via Clone, maar er werd geen rekening gehouden met speciale "magische" velden van objecten - met als gevolg dat noodzakelijke methoden/attributen verloren gingen. Uiteindelijk was de functionaliteit ongeldig, en de fout deed zich alleen voor in productie.