Perl'de iç içe yapıları derin kopyalamak için (örneğin, dizi haneleri, hane dizileri) basit atama veya standart fonksiyonlar kullanılamaz (@b = @a, %b = %a, $clone = $orig). Bu tür işlemler yalnızca yüzeysel bir kopya oluşturur: iç içe nesneler hala aynı bellek alanlarına referans verir.
Derin kopyalama için aşağıdakiler kullanılır:
Storable modülü:use Storable 'dclone'; my $deep_copy = dclone($structure);
Clone modülü: benzer bir kullanım.Unutulmamalıdır ki: tüm iç içe seviyeler, yapının içindeki referanslar da dahil olmak üzere kopyalanır.
Basit atama ile karmaşık bir veri yapısını atadığınızda: iç içe elemanlar kopyalanır mı?
Cevap: Hayır, yalnızca üst seviye kopyalanır. İçteki diziler ve haneler, orijinal ile kopya arasında paylaşılan kalır.
my $orig = { a => [1,2,3], b => { x => 7 } }; my $copy = $orig; $copy->{a}[0] = 99; # $orig->{a}[0] — o da 99 olacak!
Yalnızca derin kopyalama kullanmak tamamen bağımsız bir kopya verecektir.
Hikaye 1
REST API uygulamasında, talepleri çeşitli müşteriler için normal bir atama ile kopyaladık. Sonuç olarak, bir müşterinin yanıtındaki değişiklik hemen diğerlerinde yansıyordu — çünkü hepsi aynı iç içe veri yapısıyla çalışıyordu.
Hikaye 2
Karmaşık dizi yapılarının verilerini toplarken, iç içe seviyeleri unutarak push (push @new, @old) ile kopyalama yaptık. İçteki bir hanenin rastgele değiştirilmesi, tüm toplamların verilerini bozdu — hata uzun süre tespit edilemedi.
Hikaye 3
Logları işlemek için, skripte yapıyı Clone ile kopyaladık ama nesnelerin özel "sihrî" alanlarını göz önünde bulundurmadık — dolayısıyla gerekli yöntemleri/özellikleri kaybettik. Sonuç olarak, işlevsellik geçersiz hale geldi ve hata sadece canlı ortamda yeniden üretildi.