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.. :)