Ruby ile BaÅŸlangıç – Hata Yakalama – 1

Merhabalar,

Ruby ile ilgili yeni yazıma baÅŸlamadan önce, The Marmara Pera’nın üstünde bulunan dev ekrana pazar günü saat 22:00 gibi “When you see that I hope, you know I loved you” yazan, aşık arkadaşı tebrik etmek isterim. Ben gördüm umarım görmesini istediÄŸin kiÅŸi de görmüştür :)

Bugünkü konumuz başlıktan anlaşılacağı gibi durum kötü giderse yapılacak olan işlemler üzerine deyinmek olacak. Öncelikle geçmişten günümüze bu işler nasıl yapılıyordu inceleyelim. Aslında önümüzde ik şeçenek mevcut bunlardan ilke biraz eski moda olan fakat halen kullanılan bir yöntem olan geri dönüş değerini kullanmak;
Örnek vermek gerekir ise;
[ruby]
# BAD, VERY BAD CODE for Ruby
HATAYOK = 0
HATAILK = 1

def hataDon(no)
printf “Ä°ÅŸlenen deÄŸer = %i\n”, no
if no == 0
return HATAILK
else
return HATAYOK
end
end

donenDeger = hataDon(15)
if donenDeger != HATAYOK
printf “Bir hata var numarası = %i\n”, donenDeger
end

donenDeger = hataDon(0)
if donenDeger != HATAYOK
printf “Bir hata var. Numarası = %i\n”, donenDeger
end[/ruby]
Fakat bu çok kötü bir yöntemdir.. Lütfen bu şekilde kod yazmayın, yazıyorsanız hemen bırakın. Ruby programlama dilini bu şekilde kullanmak, mühendislik bilimine saygısızlık niteliğinde olabilir.

Ä°kinci bir yöntem ise ‘ayrıcalıklı durum’ yönetimidir. Bazı konuları baÅŸtan belirtelim, bu yöntemi kullanmak Ruby dili için çok küçük bir performans kaybına neden olur, bu kayıp da ihmal edilebilir bir kayıptır. GC(Garbage Collector) tarafından kontrol edilen kodlarınızın ek olarak ayrıcalıklı hata yakalayıcısı tarafından kontrol edilmesi sisteme %1 bile yük bindirmez. DiÄŸer tüm GC bulunan dillerde de bu iÅŸlem bu ÅŸekildedir. Yalnızca C/C++ gibi herhangi bir GC’ye sahip olmayan düşük seviyeli dillerde bir performans kaybına neden olur.

Hemen örneğimizi verelim;
[ruby]
begin
raise Exception.new(“Hata test”) # raise Ayrıcaklıklı durum üretmek için kullanılır.
a = b + 1 # Sistem kendi kendine ayrıcalıklı bir durum üzetir. a veya b tanımlanmamış değişkendir.
rescue SyntaxError, NameError => err
printf “Ruby bir yazım hatasına rastladı. (%s) \n”, err
rescue Exception => err
printf “Ayrıcalıklı bir durum yakalandı. (%s).\n”, err
else
printf “Hata yok.\n”
ensure
printf “Tüm durumlarda yapılacak iÅŸlemler.\n”
end[/ruby]
Bu kod’u denediÄŸimizde ekranımızda ÅŸu yazılar belirir. “Ayrıcalıklı bir durum yakalandı. (Hata test). Tüm durumlarda yapılacak iÅŸlemler.” eÄŸer ‘raise Exception.new(“Hata test”)‘ satırı silinir ise “Ruby bir yazım hatasına rastladı. (undefined local variable or method `b’ for main:Object). Tüm durumlarda yapılacak iÅŸlemler.” yazıları çıktı olarak alınır.

Kısaca Ruby’nin ürettiÄŸi hatalar ile yazılımcının ‘raise‘ ile ürettiÄŸi hataların yakalanması aynı ÅŸekilde yapılmaktadır. Bu ÅŸekilde tüm Ruby hataları ile yazılımcının ayrıcalıklı durumlarının yönetimi saÄŸlanır.

Åžimdi biraz daha detaylandıralım; Ruby, herhangi bir ÅŸekilde ‘raise‘ iÅŸlemi ile karşılaşırsa (kendisi yada yazılımcının üretmesi fark etmez) bulunduÄŸu yerden yukarı doÄŸru programın iÅŸlenmesini durdurmaya baÅŸlar. Ve bu yukarı doÄŸru çıkış esnasında ilk yakaladağı uyumlu (uyumlu sözünü daha sonra açıklayacağım) ‘rescue’ bloÄŸunu iÅŸlemeye baÅŸlar.

raise Exception.new(“Hata test”)‘ ile ‘raise Exception, “Hata test”‘ aynı anlama gelir. ‘raise‘ ifadesi ile yapılan iÅŸlem aslında yeni bir Exception sınıfı yaratıp bu nesneyi yukarı doÄŸru fırlatır. Bu fırlatma esnasında, uyumluluk kontrolü ‘rescue‘ iÅŸleminin yanında belirttiÄŸimiz nesne ile ifade edilir. Yaptığımız örnekte Exception deyimi tüm hataları yakalar, bunun nedeni tüm hata sınıflarının Exception‘dan türemiÅŸ olmasıdır. ‘SyntaxError, NameError‘ deyimi ise SyntaxError veya NameError ayrıcalıklı durumlarda bu iÅŸlem yapılacaktır anlamına gelir.

else‘ ifadesi ise; bu blok içerisinde, program akışının herhangi bir ‘rescue‘ ifadesine uÄŸramadığında çalışır, hata veya ayrıcalıklı durum oluÅŸmadı anlamında kullanılır.

ensure‘ ifadesi ise; bu blok içerisinde hata veya ayrıcalıklı durum ortaya çıksın yada çıkmasın iÅŸlenecek olan kodu belirtir.

retry‘ ifadesi; Döngülerde olduÄŸu gibi “tekrar dene” anlamını taşır. Herhangi ‘rescue‘ bloÄŸu içerisinde kullanıldığında ‘begin‘ ile belirlenmiÅŸ olan kod bloÄŸunu, oluÅŸmuÅŸ ayrıcaklıklı durumu ihmal ederek, tekrar çalıştırır. Kullanılırken dikkatli olunmalıdır, iÅŸlemin kilitlenmesine ve yavaÅŸlamasına neden olabilir. ÖrneÄŸi;
[ruby]
retrySample = false
begin
if retrySample == false
a = b + 1 # Sistem kendi kendine ayrıcalıklı bir durum üzetir. a veya b tanımlanmamış değişkendir.
end
raise Exception.new(“Hata test”) # raise Ayrıcaklıklı durum üretmek için kullanılır.
rescue SyntaxError, NameError => err
printf “Ruby bir yazım hatasına rastladı. (%s) \n”, err
retrySample = true
printf “Hata ihmal edildi, blok tekrar icra ediliyor…\n”
retry
rescue Exception => err
printf “Ayrıcalıklı bir durum yakalandı. (%s).\n”, err
else
printf “Hata yok.\n”
ensure
printf “Tüm durumlarda yapılacak iÅŸlemler.\n”
end[/ruby]

Kolay gelsin.. :)

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir