Perl, tarihsel olarak dinamik veri yapılarına sahiptir: değişken uzunlukta diziler ve ilişkilendirilmiş diziler (hash'ler). Dilin ilk sürümlerinden itibaren, boyutlarını değiştirme (diziler için push/pop, shift/unshift; hash'e anahtar ekleme/silme) yeteneğine sahiptirler. Bu esneklik, Perl'in mimarisine yerleştirilmiştir: bellek otomatik olarak yönetilir, konteynerler programcının açık müdahalesi olmadan genişleyebilir veya daralabilir.
Kütle değişiklikleri sırasında sorunlar ortaya çıkabilir: işlem sırasının optimal olmaması gereksiz bellek yeniden tahsisine yol açabilir ve yapıyı ele geçirme (örneğin, foreach döngüsü ile aynı anda bir elemanı silmek) hatalara yol açabilir.
Çözüm, yerleşik toplu işlemleri (splice, delete) kullanmak veya yeni yapılar oluşturmak için map/grep kullanmaktır; yapı üzerinde dolaşırken değiştirme işlemlerinden kaçınılmalıdır.
Kod örneği (koşula göre toplu silme):
# Diziden çift indeksli elemanları sil my @arr = (1..10); @arr = grep { $_ % 2 } @arr; # Sadece tekler kalacak # Toplu ekleme push @arr, (11, 13, 15); # Hash için my %hash = (a => 1, b => 2, c => 3, d => 4); delete @hash{ grep { $hash{$_} % 2 == 0 } keys %hash }; # çift değerleri sileceğiz
Anahtar özellikler:
Foreach döngüsü ile diziden elemanları güvenli bir şekilde silmek mümkün mü?
Cevap: Hayır, bu yanlışa yol açar - indeksler kayar ve döngü "atlayarak" elemanları geçer. Filtreleme (map/grep) kullanın veya splice ile ters sırada iterasyon yapın.
Autovivification yeni iç içe yapılar oluşturmayı nasıl etkiler?
Cevap: Mevcut olmayan bir elemana erişirken Perl otomatik olarak bir yapı oluşturur, bu süre kazandırır, ancak beklenmedik yan etkilere ("boş" yapılar oluşturma) yol açabilir. Kesin bellek yönetimi gerekiyorsa bunu manuel olarak kontrol edin.
my %h; $h{newkey}{subkey} = 1; # Perl otomatik olarak alt hash oluşturur!
Bir hash'teki mevcut bir değeri yeniden yazmak her zaman hızlı bir süreç midir?
Cevap: Skalar ve çoğu basit türler için evet; ancak değer büyük bir yapı veya referans ise referans sayımı maliyetleri olabilir. Büyük yapılarınızı yerinde değiştirmek daha iyidir, referansları yeniden yazmaktan kaçının.
Geliştirici, bir foreach döngüsü sırasında diziden elemanları siler ve sonuç olarak verinin bir kısmı dizide kalır, döngü düzgün çalışmaz.
Artılar:
Eksiler:
@arr = grep { koşul } @arr kullanılarak filtreleme yapılır veya indeksler sonundan silme işlemi gerçekleştirilir.
Artılar:
Eksiler: