"Yükselt" foo "ve" Exception.new ("foo") "arasındaki fark nedir?


Yanıtlar:


121

Teknik olarak, birincisi, mesaj olarak ayarlanmış bir RuntimeError hatası "foo", ikincisi ise mesaj olarak ayarlanmış bir İstisna oluşturur "foo".

Pratik olarak, ilkini ne zaman kullanmak isteyeceğinizle ikincisini ne zaman kullanmak istediğiniz arasında önemli bir fark vardır.

Basitçe söylemek gerekirse, muhtemelen bir RuntimeErrordeğil Exception. Bağımsız değişken içermeyen bir kurtarma bloğu RuntimeErrorss'ları yakalayamaz Exception. Dolayısıyla Exception, kodunuzda bir yükseltirseniz , bu kod onu yakalamayacaktır:

begin
rescue
end

Yakalamak için şunu Exceptionyapmanız gerekecek:

begin
rescue Exception
end

Bu, bir anlamda, Exceptiona'nın "daha kötü" bir hata olduğu anlamına gelir RuntimeErrorçünkü ondan kurtulmak için daha fazla iş yapmanız gerekir.

Hangisini istediğiniz, projenizin hata işlemesini nasıl yaptığına bağlıdır. Örneğin, arka plan yordamlarımızda, ana döngü, RuntimeErrorsonları yakalayacak , rapor edecek ve sonra devam edecek boş bir kurtarmaya sahiptir . Ama bir veya iki durumda, arka plan programının gerçekten bir hata nedeniyle ölmesini istiyoruz ve bu durumda Exception, doğrudan "normal hata işleme kodumuzdan" geçen ve çıkan bir anı yükseltiriz .

Ve yine, eğer kütüphane kodu yazıyorsanız, muhtemelen a RuntimeErrordeğil, istersiniz Exception, çünkü kütüphanenizin kullanıcıları boş bir rescuebloğun yakalayamayacağı hatalar ortaya çıkarsa şaşıracak ve nedenini anlamaları biraz zaman alacaktır.

Son olarak, RuntimeErrorsınıfın bir alt sınıfı olduğunu söylemeliyim StandardErrorve gerçek kural, raise herhangi bir tür nesneyi yapabilmenize rağmen , boşluk rescuevarsayılan olarak yalnızca miras alan her şeyi yakalayacaktır StandardError. Geri kalan her şey özel olmalıdır.


2
çok bilgilendirici, teşekkürler. bir kaç şey: [1] Son paragraf en çok söz etmedi irb şeye keşfetmeye aydınlatıcı ve bana izin buydu: RuntimeError < StandardError < Exception[2] Bu nedenle, kod, ikinci bloğu o olacak bir özel durum ve RuntimeError [3] hem yakalamak "Çıplak" yükseltme ve kurtarmanın söz konusu İstisna [4] ile çalışması ilginç / tuhaftır belki de temel kural RuntimeError'ı istemci koduna yükseltmek, ancak kişinin kendi kodunun içindeki kendi özel İstisnalarını yükseltmek ve kurtarmaktır?
John Bachir

1
[1, 2] Evet. [3] emin değilim ... [4] En profesyonel olarak kod yazarken, miras alan özel hata türleri oluşturma eğilimindeyim StandardError. Birkaç satırdan daha karmaşık olmak zorunda değil class MissingArgumentsError < StandardError; end.
Daniel Lucraft

Çok bilgilendirici, ancak ne tür durumlarda libraray yazmak için çalışma zamanı hatası tercih edilirse çalışma zamanı hatası yerine bir İstisna atmak isteyeceksiniz?
Chihung Yu

35

Resmi belgelerden:

raise   
raise( string )
raise( exception [, string [, array ] ] )

Hiçbir argüman olmadan, istisnayı $!yükseltir veya bir RuntimeErrorif $!is nil'i yükseltir . Tek bir Stringbağımsız değişkenle, bir RuntimeErrordizge ile bir mesaj olarak a yükseltir . Aksi takdirde, ilk parametre bir Exceptionsınıfın (veya Exceptiongönderildiğinde istisna döndüren bir nesnenin) adı olmalıdır . İsteğe bağlı ikinci parametre, istisna ile ilişkili mesajı ayarlar ve üçüncü parametre, bir geri arama bilgileri dizisidir. İstisnalar, begin...endblokların kurtarma hükmü tarafından yakalanır .

raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.