ProgramlamaPerl geliştirici (backend/data)

Perl'de iteratörler ve üreticiler nasıl uygulanır ve çalışır? Yaygın olarak kullanılan tembel hesaplama desenleri nelerdir ve bunların kısıtlamaları nelerdir?

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

Cevap

Perl'de Python'daki gibi yerleşik üreticiler yoktur, ancak kaplamalar, yerel değişkenlerde durum takibi ve üretici işlevleri kullanarak tembel hesaplamalar ve iteratörler uygulanabilir:

sub counter { my $x = shift; return sub { return $x++; }; } my $it = counter(5); print $it->(), ", ", $it->(); # 5, 6

Karmaşık iteratörler için genellikle CPAN modülleri (Iterator::Simple, List::Gen) kullanılır. Klasik tembel desen, kaydedilmiş durum ile anonim bir alt program döndürmektir.

Eksileri: yield için yerleşik destek yok, birçok CPAN modülünün bileşenliği eksik. Ayrıca, özyineleme yığın boyutları ile sınırlıdır.

Tuzak sorusu

Perl'de belleği taşmadan sonsuz tembel Fibonacci sayı listesi oluşturulabilir mi?

Cevap: Evet, kaplama ile:

sub fibonacci { my ($a, $b) = (0, 1); return sub { ($a, $b) = ($b, $a+$b); return $a; }; } my $fib = fibonacci(); print $fib->(), ", ", $fib->(), ", ", $fib->();

Ancak sonuçları bir diziye koyarsanız, zamanla bellek taşmasına neden olur (yani gerçekten "tembel" olan yalnızca üreticidir).

Konuyla ilgili ince ayrıntılardan ötürü gerçek hata örnekleri


Hikaye

Bir projede devasa bir dosyayı dolaşmak için kendi iteratörümüz yazılmıştı, bu bir nesne içinde bir dizi aracılığıyla gerçekleştirildi. İteratör bütün dosyayı belleğe yüklüyordu — ve dosya büyüdükçe hizmet, birden fazla örnekle çalışırken OOM hatası vermeye başladı.


Hikaye

Rapor için parça sıraları için kaplama-üretici bellek sızıntısına neden oldu — kaplama içinde büyük bir giriş verisi dizisine yanlışlıkla tutulan bir referans, çöp toplayıcının çalışmasını engelledi.


Hikaye

Derinliği takip etmeden özyineleme ile karmaşık bir üretici uygulama girişimi, gerçekten büyük veriler işlenirken yığın sınırını aşmaya neden oldu, beklenen "tembel" dolaşma yerine.