Dinamik veri yapılarıyla çalışmak, her Perl geliştiricisi için anahtar noktalarından biridir. Perl, karmaşık iç içe yapılar oluşturmak ve yönetmek için güçlü araçlar sağlar: diziler dizileri (array of arrays), hash'ler hash'leri (hash of hashes) ve bunların tüm kombinasyonları. Dilin esnekliği, rastgele derinlikte yapılar oluşturmaya olanak tanırken, referans modelinin özeliklerini ve elemanlara güvenli erişim yollarını net bir şekilde anlamak gerekmektedir.
Perl başlangıçta, C veya Java gibi çok boyutlu diziler için bir sözdizimi sunmuyordu, bu nedenle iç içe yapıların uygulanması referanslar kullanılarak inşa edilmektedir. Bu, büyük bir esneklik sağlar, ancak dikkatsiz bir geliştirici için bazı tuzaklar açar.
Birçok geliştirici dizilerle ve bunların referanslarıyla doğrudan çalışmayı karıştırır ve yanlış sözdizimiyle bir elemana erişmeye çalışır. Hatalar çoğunlukla iç içe elemanların (auto-vivification) yanlış başlatılması, referanslar ve doğrudan değerler arasındaki karışıklık ve elemanların yanlış kopyalanması ve silinmesiyle ilgilidir.
Perl'de iç içe yapılarda her zaman referanslar kullanılır:
Kod örneği:
# Diziler dizileri my @matrix; $matrix[0] = [1, 2, 3]; $matrix[1] = [4, 5, 6]; print $matrix[1]->[2]; # 6 # Hash'ler hash'leri my %family; $family{'Jack'} = { age => 45, city => 'Moscow' }; print $family{'Jack'}->{age}; # 45
Anahtar özellikler:
->) ve doğrudan indeksleme ([], {}) arasında net bir ayrımReferanslar kullanmadan çok boyutlu bir dizi oluşturmak mümkün müdür?
Hayır, standart Perl sözdizimi, referans olmadan çok boyutlu dizilerle doğrudan çalışmayı desteklememektedir. $array[1][2] gibi bir sözdizimi, $array[1]'in başka bir diziye referans olduğunu ima eder.
Auto-vivification (hata ile erişim yoluyla iç içe yapıların otomatik olarak oluşturulması) ne gibi tehlikeler taşır?
Auto-vivification, yanlış bir anahtar ile rastgele erişim sırasında yapıların beklenmedik bir şekilde oluşmasına neden olabilir; bu, verilere "boş" değerler ekler ve iç içe bir hash silindikten sonra bile dış yapı gereksiz anahtarlar içermeye devam eder.
my %h; $h{top}{sub}{leaf} = 5; # Tüm ara elemanlar otomatik olarak oluşturulacak
Örneğin, my @b = @a; gibi iç içe bir yapıyı normal bir şekilde kopyaladığımızda, eğer @a referanslar içeriyorsa ne olur?
Sadece referanslar kopyalanır, iç içe yapıların içeriği değil. Her iki dizi de iç içe nesnelere aynı nesneleri gösterir ve bir değerde yapılan bir değişiklik her iki yapıda da yansır.
$array->[1][2] vs $array[1][2], $hash{key}[0] vs $hash->{key}->[0])Programcı, diziler dizisini basit atama ile oluşturdu: my @a = @b;, burada @b diziler referanslarından oluşuyordu. Sonuçta, bir dizideki değişiklik diğerini etkiledi ve veri güncelleme sırasında hata aldı.
Artılar:
Eksiler:
Geliştirici, başka sistem parçaları arasında ortak referansların olmaması için her elemana göre derin kopyalama yapan bir rekürsif fonksiyon veya Storable modülü kullanmıştır.
Artılar:
Eksiler: