Perl, başlangıçta sistem yöneticiliği için bir betik dili olarak tasarlandığından, geleneksel hata işleme modeli daha çok prosedürel bir yapıdaydı. Ancak zamanla dilde genişletilmiş istisna ve hata işleme teknikleri ortaya çıktı.
Perl'in ilk sürümlerinde hatalar, işlevlerin döndürdüğü değerler ve küresel değişken $! ile kontrol edilerek yakalanıyordu; daha sonra eval yapıları (dinamik yakalama) ortaya çıktı ve Try::Tiny gibi modüller kısa, güvenli try-catch kalıplarını ekledi.
Standart Perl, yerleşik bir try-catch sözdizimine sahip değildir. Hatalar, hem Perl kodunda hem de dış çağrılarda (örneğin, dosya açma) meydana gelebilir. Hatalar açık bir şekilde işlenmezse, program tahmin edilemeyen bir durumda çalışmaya devam edebilir. Hata yakalama tekniği, bağlama, uygulamanın karmaşıklığı ve güvenilirlik gereksinimlerine göre özenle seçilmelidir.
eval fonksiyonu kullanılır, potansiyel olarak tehlikeli kod bir blok içinde sarılır ve $@ içeriği işlem sonrası analiz edilir.die kullanılır. Daha özel hata oluşturma ve daha önce tanımlanmış istisnaların tekrar fırlatılması için sinon çerçevesi kullanılır.Kod Örneği — Try::Tiny ile hata işleme:
use Try::Tiny; try { open my $fh, '<', 'file.txt' or die "Dosya açılamıyor: $!"; while (<$fh>) { print $_; } } catch { warn "Hata oluştu: $_"; };
$@ ve scope tuzakları ile ilgili tipik eval hatalarından kaçınmaya yardımcı olur.Eval bloğu hangi durumda sistem hatasını yakalamaz?
Eval, C kütüphanelerinde (örneğin, XS kodundan kaynaklanan SEGFAULT) kritik bir çıkış olduğunda hatayı her zaman yakalayamaz. Eval, yalnızca Perl kritik hataları ile çalışır, C uzantıların çökmesiyle değil.
İç içe eval bloklarında $@ değişkeni ne olur?
İçte bir eval çağrıldığında ve çıktığında $@ değeri üzerine yazılır. Bu nedenle, her eval'dan sonra $@'yı bir değişkende saklamak, orijinal hatayı kaybetmemek için iyidir.
Try::Tiny gibi yardımcı modüller $@ değişkenini catch/try içinde yerel olarak neden tanımlar?
Çünkü Perl, yalnızca try (eval) başarılı bir şekilde çıktığında $@'yı otomatik olarak temizler. Hata çıkışı, next, last gibi durumlar, $@'nın temizlenmemesine neden olabilir ve sonraki kodda "hayalet" bir hata meydana gelebilir. Try::Tiny gibi modüller, bunu sağlamak için scope-local bir değişken oluşturur.
Örnek:
try { die "Boom!"; } catch { print "Yakalandı: $_ "; # $_ - catch içindeki hata tuzağı };
$@ değerinin görmezden gelinmesi (hata göz ardı edildi)$@'nın değiştirilmesi ve saklanmamasıVeri aktarımında, veritabanına bağlanırken hata, eval ile yakalanır ancak $@ değeri saklanmaz, hata kaydı yapılmaz. Bir sonraki eval'da başka bir hata oluştuğunda, ilk hata tamamen kaybolur.
Artılar:
Eksiler:
Kritik bölümlerin işlenmesi için Try::Tiny kullanımı, tüm hataları ayrı bir günlüğe yazar, orijinal hata saklanır ve ekrana düzgün bir şekilde iletilir.
Artılar:
Eksiler: