Ruby/Sıradışı Durumlar
←Sınıflar ve nesneler | Söz Dizimi→
Bu sayfanın orjinalinde birşey yok. Ben size ruby-doc.com sayfasından öğrendiklerimi yazayım.
Şimdiye kadar kodlarımızı mükemmel dünyada yazdık, hiçbir şeyin yanlış gitmediği. Tüm kütüphane çağrıları başarılı, kullanıcılar her zaman doğru bilgi giriyor, kaynaklar bol ve ucuz. Artık bu değişecek, gerçek dünyaya hoş geldiniz!
Gerçek dünyada hatalar oluşur. İyi programlar (ve programcılar) bunları öngörür ve bunları zarif bir şekilde ele almak için gerekli ayarlamaları yaparlar. Sıklıkla , kodlar hataya düştüklerinde ne yapacaklarına dair bilgi sahibi değildir. Örneğin olmayan bir dosyayı açmak istediğinizde bir fatal hata oluşur, sizin dosya işleme modülünüz ne yapacak?
Geleneksel erişim dönen değerleri kullanmaktır. open
metodu , hataya düştüğünü belirten bazı değerler döner. Bu değer çağıran rutinlerde , biri onunla ilgilenene kadar yukarı doğru yayılır (propagate).
Ama mesela open , read ve close her biri bir hata dönebilir. Kodumuzda her birini çağırırken dönen değeri işlemek ve ona göre davranış belirlemek çok sıkıntı verecektir.
Bu tip durumlarla başa çıkmak için bütün dillerde "Sıradışı Durumlar" (Exceptions) adıyla bilinen teknikler kullanılır. Exception'lar hata hakkında bilgiyi bir nesnede toplamanızı sağlar ve bu sıradışı durum nesnesi sistem bu durumu bildiğini belirten bir kod bulana kadar çağrı sıralamasında geri doğru yayılır.
Exception Sınıfı
[düzenle]Sıradışı durum hakkında bilgi içeren paket Exception sınıfı ya da onun çocuklarından bir sınıfın oluşumudur. Sınıf Hiyerarşisi şöyle:
- Exception
- NoMemoryError
- ScriptError
- LoadError
- Gem::LoadError
- NotImplementedError
- SyntaxError
- LoadError
- SecurityError
- SignalException
- Interrupt
- StandardError
- ArgumentError
- Gem::Requirement::BadRequirementError
- EncodingError
- Encoding::CompatibilityError
- Encoding::ConverterNotFoundError
- Encoding::InvalidByteSequenceError
- Encoding::UndefinedConversionError
- FiberError
- IndexError
- KeyError
- StopIteration
- IOError
- EOFError
- LocalJumpError
- Math::DomainError
- NameError
- NoMethodError
- RangeError
- FloatDomainError
- RegexpError
- RuntimeError
- Gem::Exception
- SystemCallError
- ThreadError
- TypeError
- ZeroDivisionError
- ArgumentError
- SystemExit
- Gem::SystemExitException
- SystemStackError
Sıradışı Durumu İşlemek
[düzenle]Genel yapı şu şekildedir:
begin
output = 5/0
puts "başarılı"
rescue Exception
STDERR.puts "Başarısız : #{$!}"
raise
end
begin
ile başlayan blok bir hata olmazsa çalışacak kodları içerir. rescue
bloğu ise bir exception (sıradışı durum) oluştuğunda çalışacak kodları içerir. Orada kullanılan $!
gloabal değişkeni oluşan hataya karşılık Ruby sisteminin ürettiği hata mesajını içerir. Bu kodun çıktısı:
Başarısız : divided by 0
olur, ayrıca bölme hatası olduğu için zaten Ruby'dehata mesajı verecektir. Bu sadece örnek olarak verilmiş kısa bir kod.
Sıradışı durum işleme bloğu içinde birden fazla rescue
bloğu olabilir.
begin
eval string
rescue SyntaxError, NameError => boom
puts "String derlenemedi: " + boom.to_s
rescue StandardError => bang
puts "Kod çalıştırılırken hata oldu: " + bang.to_s
end
Bu kodu eğer :
string = "put 'merhaba'"
ile çalıştırırsak
String derlenemedi: undefined method `put' for main:Object
hatası verir. Eğer:
string = "puts 5/0"
ile çalıştırırsak
Kod çalıştırılırken hata oldu: divided by 0
hatası verir.
Hatayı Kodla Üretmek
[düzenle]Şimdiye kadar oluşan hataları işledik. İstersek kendimiz de kodumuzla hata üretebiliriz.
raise
bize
excep.rb:1:in `<main>': unhandled exception
verir.
name = nil
raise "İsim yok" if name.nil?
bize
excep.rb:2:in `<main>': İsim yok (RuntimeError)
verir.
names = ["Ümit", "Ahmet", "Sıla"]
i = 4
if i >= names.size
raise IndexError, "#{i} >= #{names.size} (boyutu aştı)"
end
bize
excep.rb:4:in `<main>': 4 >= 3 (boyutu aştı) (IndexError)
verir.
raise ArgumentError, "İsim çok uzun", caller
bize
excep.rb: İsim çok uzun (ArgumentError)
verir. Bu örnekte parametrede caller
metodunu vermesek
excep.rb:1:in `<main>': İsim çok uzun (ArgumentError)
verecekti.