ProgramlamaKıdemli Perl Geliştirici, Backend/Fullstack

Perl'de closure'lar ve anonim alt programlarla çalışma özelliklerini açıklayın. Onları nasıl doğru bir şekilde kullanmalıyız, ince noktalar nerelerde ortaya çıkıyor ve bellek sızıntılarını nasıl önleyebiliriz?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Perl'de anonim alt programlar ve closure'lar desteklenmektedir. Anonim alt programlar, isim olmadan sub ile tanımlanır ve kodun bir referansını döndürür. Closure, oluşturuldukları anda var olan değişkenleri içeren leksik bir alanı 'yakalar' ve bir alt programdır.

Anonim alt program ve closure örneği:

sub make_incrementer { my $inc = shift; return sub { $_[0] + $inc }; } my $inc10 = make_incrementer(10); print $inc10->(5); # 15'i yazdırır

Closures, fonksiyon fabrikaları, jeneratörler ve callback'ler oluşturmak için aktif olarak kullanılır (örneğin, map/grep, olay işleyicileri gibi).

Önemli bir nokta: Eğer bir closure, kendisine (doğrudan veya yapılar aracılığıyla) işaret eden değişkenlere işaret ediyorsa, dairesel referans oluşur ve bellek sızıntısına neden olabilir.

İkna edici soru

Closure içinde kapatılan değişkenler ne zaman serbest bırakılır? my ile our değişkenleri için farklılık var mı?

Cevap: Closure içinde kapatılan my değişkenleri, closure'a en az bir referans olduğu sürece yaşamaya devam eder. Fonksiyon tamamlandığında serbest bırakılmazlar, yaşam süreleri — tüm closure'ın yaşam süresidir. our değişkenler için böyle bir davranış yoktur — tüm closure'lar için erişilebilirler ve program sona erdiğinde serbest bırakılırlar. Closure'ı silmeyi unutarak bellek sızıntısına neden olabilirsiniz.

Sorun örneği:

my $cref; { my $val = 5; $cref = sub { $val++ }; } # $val hala mevcut, $cref canlı olduğu sürece

Bilinmeyen ince detaylardan kaynaklanan gerçek hata örnekleri


Hikaye

Sunucu uygulamasında her kullanıcı için callback için bir closure bağlamı oluşturuluyordu. Ancak closure, kullanıcı yapısına da referans veriyordu, bu da dairesel referansa neden oluyordu. Bu nedenle, garbage collector, kullanıcı nesnelerini logout sonrasında bile temizlemiyordu — bellek sızıntıları üstel bir şekilde artıyordu.


Hikaye

Olayları arka planda işlemek için bir demon uygulamasında kapalı sayaç değişkenlerine sahip closures kullanıldı, ancak referans verdikleri dizileri sıfırlamayı unuttular. Sonuç olarak — birkaç unutulan closure nedeniyle eski mesaj verileri birikti, demon arızalanmadan önce yığılı bellek temizliği yapmak zorunda kaldık.


Hikaye

Bir geliştirici, closure içinde our değişkenini kullanmaya çalıştı, 'kapalı' bir davranış bekliyordu — ancak tüm closures ortak bir değişkeni paylaştı, bu da paralel yürütme sırasında veri yarışlarına neden oldu. Hata, farklı parametrelerle aynı anda çalışan kullanıcılar arasında ortaya çıktı (hatalı hesaplamalar).