Perl'de, bazı diğer dillerde olduğu gibi çok boyutlu diziler için yerleşik bir sözdizimi yoktur. Bunun yerine, her üst düzey öğe başka bir diziye referans olan dizi dizileri kullanılır. Bu yapı, iki boyut veya daha fazla iç içe geçmişlik gerektiren tablolar, matrisler ve diğer veri yapılarını esnek bir şekilde modellemeyi sağlar.
Perl başlangıçta metin işleme ve basit yapılarla çalışma için geliştirildi, ancak referansların (Perl 5'ten itibaren) ortaya çıkmasıyla geliştiriciler karmaşık iç içe yapılar oluşturma fırsatına sahip oldu – örneğin, dizi dizileri veya dizi içindeki hash.
Yeni kullanıcılar için en büyük yanılgı: basit bir şekilde iki boyutlu bir dizi oluşturmaya çalışmak – örneğin @matrix = ( (1,2), (3,4) ) şeklinde tanımlamak. Bu yaklaşım, öğelerin iç içe yapılar yerine skalar değerler olarak açılmasından dolayı istenen sonucu vermez. Ayrıca, dizilerin kopyalanmasında da sık yapılan bir hata vardır: yüzeysel kopyalama beklenmedik yan etkilere yol açar.
Perl'de çok boyutlu diziler, dizilere referanslar aracılığıyla oluşturulur. Doğru bir şekilde başlatma şöyle görünür:
my @matrix; for my $i (0..2) { for my $j (0..2) { $matrix[$i][$j] = $i * $j; } } # Elemanlara erişim: $matrix[1][2]
Ya da anonim referanslar aracılığıyla:
my $matrix = [ [1,2,3], [4,5,6], [7,8,9] ]; print $matrix->[1][2]; # 6
Temel özellikler:
Diğer dillerdeki gibi, sadece parantezler içinde parantezler tanımlayarak çok boyutlu diziler oluşturulabilir mi?
Hayır. Perl bu durumda elemanları sıradan bir liste gibi açar. Sadece referans kullanımı doğrudur.
Hatalı kod örneği:
my @matrix = ((1,2,3),(4,5,6),(7,8,9)); # Elemanlar sırayla gelir print $matrix[3]; # 4, [4,5,6] değil - hatalı çalışma
Doğru yol:
my @matrix = ( [1,2,3], [4,5,6], [7,8,9] ); print $matrix[1][2]; # 6
Eğer dizi dizisini basit atama ile kopyalarsak ne olur?
Sadece üst düzey kopyalanır, iç içe diziler aynı bellek alanlarına referans verecektir.
Örnek:
my @a = ( [1,2], [3,4] ); my @b = @a; $a[0][0] = 99; print $b[0][0]; # 99, oysaki 1 bekliyorduk - yüzeysel kopyalama!
Perl'in yerleşik özellikleri ile iç içe diziyi "derin" olarak kopyalamak mümkün mü?
Hayır, Perl iç içe yapılar için standart bir derin kopyalama operatörü sunmaz. Storable modülünü veya rekürsif bir fonksiyonu kullanmanız gerekir.
Storable ile örnek:
use Storable 'dclone'; my $deepcopy = dclone(\@matrix);
Geliştirici, dizi novasi ile basit bir şekilde iki boyutlu bir matris oluşturur ve bunu atama ile kopyalar:
my @m1 = ([1,2],[3,4]);
my @m2 = @m1;
$m1[0][0] = 77;
print $m2[0][0];
Avantajlar:
Dezavantajlar:
Derin kopyalamak için Storable modülünün kullanımı:
use Storable 'dclone'; my @m1 = ([1,2],[3,4]); my $m2 = dclone(\@m1); $m1[0][0] = 77; print $m2->[0][0]; # 1
Avantajlar:
Dezavantajlar: