Perl'de atama sonucu (ve dolayısıyla diziler ve hash'lerle çalışma) bağlama göre değişir.
my @arr = (10, 20, 30); my $count = @arr; # $count == 3 my ($first, $second) = @arr; # $first == 10, $second == 20
Hash'ler için:
my %h = (a=>1, b=>2, c=>3); my $size = %h; # $size == 3 modern Perl sürümlerinde, ama daha önce böyle değildi!
Bir dizinin içeriğini kopyalamak yerine tam olarak bir referansı atamaktan kaçının!
Dizi ataması ile dizi içeriğinin kopyalanması arasındaki fark nedir?
Cevap:
my @a = (1,2,3); my $ref = \@a; # $ref — bir diziye referans, $ref üzerinden yapılan değişiklikler @a'da görünür my @b = @a; # @b — yeni bir dizi, @b'deki değişiklikler @a'yı etkilemez # Karşılaştırın: push @$ref, 4; # @a artık (1,2,3,4) push @b, 5; # @a (1,2,3,4) olarak kalır; @b — (1,2,3,5)
Hikaye 1
Projede bir diziyi alt programa referansla geçirirken bunun bir referans olduğunu anlamadık; fonksiyon çağrıldığı yerinde onu değiştirdi. Hatalar geldi — çağıran koddaki veri yapısı "bozulmuş" olarak kaldı. Kopya bekliyorduk, alias aldık.
Hikaye 2
Mühendis, skalar atama
%h'nin gerçekteki çift sayısını döndüreceğini düşündü. Ancak eski Perl sürümlerinde bu davranış farklıydı: slot/bucket sayısı dönerdi, uzunluk değil! Sonuç olarak bazen 3 yerine başka bir sayı döndü, bu da istatistiği bozdu.
Hikaye 3
Büyük bir ETL sisteminde diziler referansla kopyalanıyordu ve sonra birbiriyle beklenmedik şekilde veri kaymayı yaşadılar çünkü hepsi aynı diziyi kullanıyordu, bağımsız kopyalar değil. Hatanın teşhisi birkaç gün sürdü.