Dizi dizileri, hash hash'leri ve diğer karmaşık veri yapıları Perl'de referanslar aracılığıyla inşa edilir. Bu yaklaşım, hiyerarşik/dağınık yapıların oluşturulmasını kolaylaştırır, ancak erişim, kopyalama ve değiştirme sırasında dikkatli olunmasını gerektirir, çünkü varsayılan olarak içerik değil, referans saklanır.
Başlangıçta Perl yalnızca düz diziler ve hash'ler destekliyordu, iç içe geçmişlik yoktu. Daha sonra referans desteği geldi ve herhangi bir kombinasyon oluşturulmasına izin verdi: dizi dizileri, hash hash'leri, "ağaç", "graf" gibi yapılar.
Karmaşık yapılarla çalışmak, erişim, yazma ve kopyalama işlemlerinin referanslarla çalıştığını hatırlamayı gerektirir. Hatalar genellikle bir eleman ile elemanın referansı arasında karışıklıktan kaynaklanır. Bu, bir yerdeki verilerin değiştirilmesinin, referansın programın birden çok kısmı tarafından aynı anda kullanılması durumunda tüm yapı üzerinde yansıması gibi sayısız hatalara yol açar.
Dizi dizisi oluşturmak için:
my @matrix; for my $i (0..2) { for my $j (0..2) { $matrix[$i][$j] = $i * $j; } } print $matrix[1][2]; # 2
Hash hash'i için:
my %data; $data{'user1'}{'name'} = 'Alex'; $data{'user1'}{'age'} = 20;
Karmaşık yapılar için:
my %complex = ( 'list' => [1, 2, 3], 'map' => { foo => 'bar' }, );
Bir diziyi diğerine atamaya çalışırsak yapı kopyası ne olur?
Böyle bir atama iç içe yapıları kopyalamaz, yalnızca onlara olan referansları kopyalar (yani "yüzeysel kopyalama" gerçekleşir).
my @a = ([1,2], [3,4]); my @b = @a; $a[0][0] = 99; printf "$b[0][0] "; # 99 gösterir, çünkü @b, @a'nın referanslarını içerir
$array[$i] ile $array->[$i] arasındaki fark nedir?
İlk seçenek, bir dizimiz varsa çalışır, ikinci seçenek ise bir diziye referans gösteren bir skalarimiz varsa çalışır. İç içe geçmiş yapılar için en yaygın sözdizimi - oku gösterimi ($foo->[0]).
Neden standart Perl'de yapının kopyasını alırken dclone kullanamıyoruz?
Çünkü dclone, Perl'in temel paketinde yer almaz. Karmaşık yapıların derin kopyalamaları için Storable modülü ve dclone fonksiyonu kullanılır:
use Storable 'dclone'; my $deep_copy = dclone(\%complex);
Bir projede diziyi diziyi sıradan atama ile kopyalarlar (@copy = @org), ve bir dizi değişiklikten sonra aniden "orijinal" verilerin kopya ile birlikte değiştiğini fark ederler.
Artıları:
Eksileri:
Dizileri ve hash'leri kopyalamak için Storable modülünü ve dclone fonksiyonunu kullanırlar, bunu kodda açıkça belgelerler ve nerede referans olduğunu belirtirler.
Artıları:
Eksileri: