Hata İşleme: rescue deyimi
Önceki VI. Oylum - Ruby Kullanıcı Kılavuzu Sonraki
Hata İşleme: rescue deyimi
Çalıştırılan bir yazılım beklenmeyen sorunlar doğurabilir. Okunmaya çalışılan bir dosya mevcut olmayabilir ya da veri kaydetmemek istediğimiz disk dolu olabilir yada kullanıcı beklenmeyen bir girdi yapabilir.
ruby>   file = open("bir_dosya")
ERR: (eval):1:in `open': No such file or directory - bir_dosya
Güçlü bir yazılım bu gibi durumları hassasiyetle yakalayacaktır. C yazılımcılarından, hata doğurabilecek her sistem çağrısının sonucunu kontrol etmeleri ve anında ne yapılacağına ilişkin karar vermeleri beklenir:
FILE *file = fopen("bir_dosya", "r");
if (file == NULL) {
  fprintf( stderr, "Dosya mevcut değil.\n" );
  exit(1);
}
bytes_read = fread( buf, 1, bytes_desired, file );
if (bytes_read != bytes_desired ) {
  /* hata giderme işlemleri... */
}
...
Bu yazılımcıları dikkatsizliğe ve ihmalciliğe iten, üstelik hataları tam olarak yakalayamayan bir yazılım yazmanıza yol açan sıkıcı bir uygulamadır. Öte yandan, işi doğru düzgün yapmak, yakalanabilecek bir çok hata olduğu için yazılımın okunabilirliğini oldukça zorlaştıracaktır.
Güncel bir çok dilde olduğu gibi Ruby'de de, yazılımcıyı ya da sonradan kodumuzu okuyan kişileri sıkıntıya sokmadan, sürprizleri kod bloklarından soyutlayan bir yolla yakalayabiliriz.
begin ile işaretlenmiş kod bloğu bir istisnayla karşılaşana dek çalıştırılır, hata durumunda denetimi rescue ile işaretlenmiş kod bloğuna verir. Eğer hiçbir istisnayla karşılaşılmazsa rescue kodu kullanılmaz. Aşağıdaki yöntem bir metin dosyasının ilk satırını döndürür, bir istisna ile karşılaşırsa nil değerini:
def first_line( filename )
  begin
    file = open("bir_dosya")
    info = file.gets
    file.close
    info  # Değerlendirmeye alınan son şey dönüş değeri
  rescue
    nil   # Dosyayı okuyamıyor musunuz? O zaman bir dizge dönmez.
  end
end
Bir problemle yaratıcı bir biçimde ilgilenmek istediğimiz zamanlar olacaktır. Örneğin dosyaya erişmek mümkün değilse standart girdi yerine başka bir şey kullanmak isteyebiliriz:
begin
  file = open("bir_dosya")
rescue
  file = STDIN
end

begin
  # ... girdiyi değerlendir ...
rescue
  # ... burada diğer istisnalarla uğraş.
end
begin kodunu tekrar çalıştırmak için rescue'nun içinde retry'ı kullanabiliriz. Bu bize önceki örneğimizi daha kısa şekilde yazmamıza izin verir:
fname = "bir_dosya"
begin
  file = open(fname)
  # ... girdiyi degerlendir ...
rescue
  fname = "STDIN"
  retry
end
Ancak burada bir kusur bulunmaktadır. Hiç olmayan bir dosya bu kodun sonsuz bir döngüde kendisini tekrar etmesini sağlayacaktır. retry'ı kullanırken bu tür durumlara dikkat etmelisiniz.
Her Ruby kütüphanesi, sizin de kendi kodunuzda yapabileceğiniz gibi, herhangi bir hata karşısında bir istisna doğurur. Bir istisnayı çıkarmak için raise kullanılır. raise tek argüman olarak istisnayı açıklayan bir dizge alır. Bu argüman isteğe bağlıdır ancak atlanmaması gereken bir husustur. Özel değişkenlerden olan $! ile sonradan ulaşılabilir.
ruby>   raise "deneme hatası"
   deneme hatası
ruby>   begin
    |    raise "dnm2"
    |  rescue
    |    print "Bir hata meydana geldi: ",$!, "\n"
    |  end
Bir hata meydana geldi: dnm2
   nil
Önceki Üst Ana Başlık Sonraki
Sınıf Sabitleri Başlangıç Hata İşleme: ensure deyimi
Bir Linux Kitaplığı Sayfası