W Perlu, przy kopiowaniu złożonych struktur danych (takich jak tablice tablic, hasze haszy), ważne jest zrozumienie różnicy między "powierzchownym kopiowaniem" (shallow copy) a "głębokim kopiowaniem" (deep copy).
Powierzchowne kopiowanie tworzy nowy kontener (na przykład tablicę lub hasz), ale elementy w nim będą odnosić się do tych samych obiektów co oryginał. To może prowadzić do nieoczekiwanego zachowania — zmiana danych w kopii wpłynie na oryginał.
Głębokie kopiowanie tworzy całkowicie niezależną strukturę, rekurencyjnie kopiując wszystkie zagnieżdżone elementy. Do głębokiego kopiowania w Perlu często używa się modułów Storable lub [Clone]:
use Storable 'dclone'; my $original = { a => [1, 2, { b => 3 }] }; my $copy = $original; # Powierzchowna kopia my $deep = dclone($original); # Głęboka kopia $copy->{a}[2]{b} = 42; # Zmienia zarówno $copy jak i $original! $deep->{a}[2]{b} = 99; # Zmienia tylko $deep
Głębokie kopiowanie zapewnia, że struktury są całkowicie odizolowane od siebie.
Czym różni się kopiowanie tablicy za pomocą przypisania zmiennej od kopiowania tablicy za pomocą odniesienia? Jak poprawnie skopiować tablicę, aby zmiany w jednej nie wpłynęły na drugą?
Często odpowiada się, że wystarczy przypisać odniesienie: $copy = \@arr; — jednak to jest błędne, ponieważ obie zmienne wskazują na tę samą tablicę. Do niezależnego kopiowania używa się:
my @copy = @original; # Teraz tablice są niezależne
Jeśli potrzebne jest kopiowanie złożonych struktur — konieczne jest głębokie kopiowanie, na przykład przez Storable::dclone.
Historia
Historia
Historia
Przy realizacji szablonów e-mail dla masowej wysyłki oryginalne struktury z zagnieżdżonymi obiektami kopiowano przez przypisanie, zmiany w tekście szablonu "przeciekały" między wysyłkami, otrzymywano nieaktualne wiadomości do odbiorców.