Konuya Giriş:
Kesitler (slices) — Perl'in güçlü bir özelliği olup, bir seferde bir dizi veya hash'ten bir grup öğe çekip atamanızı sağlar. Kesit mekanizması, Perl'in ilk sürümlerinden beri mevcut olup, Python diline benzer bir sözdizimini destekler; ama kendine özgü yürütme ve bağlam özellikleri vardır.
Sorun:
Kesitlerle ilgili en büyük zorluk, dizi ve hash kesitlerini ayırt etmek, onların skalar/listesel bağlamlarını ayırmak ve kesit ile atama yaparken (özellikle aynı dizilere veya hash'lere atama yapıyorsanız ya da tekrar eden indeksler kullanıyorsanız) dikkat edilmesi gereken ince nüanslardır. Önemli bir nokta — eğer kesitlerle yapıyorsanız yapıyı güncellemenin sonucu olarak, liste genişlemesi nedeniyle anlaşılması zor bir sonuç almanız kolaydır.
Çözüm:
Kesitleri yalnızca bilinçli bir şekilde kullanın. Verilerin kopyasını çıkarmanız gerekiyorsa — listeyi açıkça kopyalayın. Okuma ve yazma sırasında çakışmalara izin vermeyin ve bir kesit işlev veya bir ifadede argüman olarak kullanılıyorsa skalar/listesel bağlama dikkat edin.
Kod örneği:
my @array = (10, 20, 30, 40, 50); my @slice = @array[1, 3]; # (20, 40) @array[0, 2] = (100, 300); # @array artık (100, 20, 300, 40, 50) my %hash = (foo => 1, bar => 2, baz => 3); my @vals = @hash{"foo", "baz"}; # (1, 3)
Anahtar özellikler:
Yanıltıcı Soru 1: Kesit @array[2, 4] içinden "skalar" bir değer alabilir miyim, $val = @array[2, 4]?
Hayır, bu durumda $val, liste uzunluğuna (eleman sayısına) eşit olacaktır, tek bir elemanın değerine değil. Tekil indekslerle doğrudan elemanlara erişmelisiniz: $array[2].
Yanıltıcı Soru 2: Eğer kesitte tekrar eden indeksler varsa, ne kaydedilir?
Sıralı yeniden atama: soldan sağa her bir indeks için atama yapılır, sonuncusu kazanır. Örneğin:
@array[0,0] = (1,2); # $array[0] == 2
Yanıltıcı Soru 3: Sağda ve solda farklı sayıda eleman içeren kesitler atayabilir miyim?
Evet, sağda daha azsa kalanlar undef alır. Daha fazlaysa, fazlalar yoksayılarak atlanır. Bu genellikle tespit edilmesi zor hataların kaynağıdır.
Geliştirici değerleri atıyor: @array[2, 3] = ("foo");
Her iki elemanın da "foo" almasını bekliyordu ama $array[3] undef oldu.
Artıları:
Eksileri:
Değerleri haritalamak için map işlevini kullanıyor: @array[2, 3] = map { "foo" } (2, 3);
Artıları:
Eksileri: