W Perl do głębokiego kopiowania zagnieżdżonych struktur (np. hasze tablicowe, tablice haszowe) nie można używać prostego przypisania ani standardowych funkcji (@b = @a, %b = %a, $clone = $orig). Takie operacje tworzą tylko powierzchowną kopię: zagnieżdżone obiekty nadal odnoszą się do tych samych obszarów pamięci.
Do głębokiego kopiowania używa się:
Storable:use Storable 'dclone'; my $deep_copy = dclone($structure);
Clone: analogiczne zastosowanie.Ważne jest, aby pamiętać: kopiowane są wszystkie poziomy zagnieżdżenia, w tym odniesienia w strukturze.
Co się stanie przy prostym przypisaniu skomplikowanej struktury danych: czy kopiowane są zagnieżdżone elementy?
Odpowiedź: Nie, kopiowany jest tylko górny poziom. Wewnętrzne tablice i hasze pozostają współdzielone między oryginałem a kopią.
my $orig = { a => [1,2,3], b => { x => 7 } }; my $copy = $orig; $copy->{a}[0] = 99; # $orig->{a}[0] — również stanie się 99!
Tylko użycie głębokiego klonowania da całkowicie niezależną kopię.
Historia 1
W aplikacji REST API klonowano zapytania dla różnych klientów przez zwykłe przypisanie odniesienia. W rezultacie zmiany odpowiedzi jednego klienta natychmiast odbijały się u wszystkich pozostałych — ponieważ wszyscy pracowali z tą samą zagnieżdżoną strukturą danych.
Historia 2
Przy agregacji danych złożonej struktury tablic używano kopiowania poprzez push (push @new, @old), zapominając o zagnieżdżonych poziomach. Przypadkowa zmiana wewnętrznego hasha zepsuła dane wszystkich agregatów — błąd długo nie mógł zostać wykryty.
Historia 3
Do przetwarzania logów w skrypcie duplikowano strukturę przez Clone, ale nie uwzględniono specjalnych "magicznych" pól obiektów — w związku z tym utracono potrzebne metody/atrybuty. W efekcie funkcjonalność była nieprawidłowa, a błąd pojawił się dopiero w środowisku produkcyjnym.