Ruby'nin iki farklı istisna mekanizması vardır: Atma / Yakalama ve Kaldırma / Kurtarma.
Neden iki tane var?
Birini diğerini değil, ne zaman kullanmalısınız?
Ruby'nin iki farklı istisna mekanizması vardır: Atma / Yakalama ve Kaldırma / Kurtarma.
Neden iki tane var?
Birini diğerini değil, ne zaman kullanmalısınız?
Yanıtlar:
Bence http://hasno.info/ruby-gotchas-and-caveats farkın iyi bir açıklaması var:
yakalama / fırlatma yükseltme / kurtarma ile aynı değildir. catch / throw, blokları belirli bir sembol için bir catch'in tanımlandığı bir noktaya hızlı bir şekilde geri çıkmanıza izin verir, yükseltme kurtarma, Exception nesnesini içeren gerçek istisna işleme şeyleridir.
raiseçok pahalıdır. throwdeğil. Bir döngüden çıkmak için throwkullanmayı düşünün goto.
raise, fail, rescueVe ensuresap hataları olarak da bilinen istisnalarthrowve catchvardır kontrol akışıDiğer dillerin aksine, Ruby'nin atış ve yakalama istisnaları için kullanılmaz. Bunun yerine, daha fazla çalışmaya ihtiyaç duyulmadığında uygulamayı erken sona erdirmenin bir yolunu sunarlar. (Grimm, 2011)
Bir whiledöngü gibi tek bir kontrol akışı seviyesini sonlandırmak basit bir işlemle yapılabilir return. İç içe geçmiş bir döngü gibi birçok kontrol akışı düzeyini sonlandırmak ile yapılabilir throw.
Yükseltme ve kurtarma istisna mekanizması, işler ters gittiğinde yürütmeyi terk etmek için harika olsa da, normal işleme sırasında derinden iç içe bazı yapılardan atlamak bazen güzeldir. Yakalama ve atma işte burada devreye giriyor. (Thomas ve Av, 2001)
https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise , geliştirebileceğimden şüphe ettiğim mükemmel bir açıklama sunuyor. Özetlemek gerekirse, blog gönderisinden bazı kod örneklerini gittikçe nickleme:
raise/ rescue, diğer dillerden (veya Python's / ) aşina olduğunuz throw/ catchconstruct'a en yakın analoglardır . Bir hata durumuyla karşılaşırsanız ve bunu başka bir dilde yaparsanız , Ruby'de yapmalısınız .raiseexceptthrowraise
Ruby throw/ catchçalıştırmayı kırmanıza ve catch(beğen raise/ yap rescue) gibi bir şey bulmak için yığına tırmanmanıza izin verir , ancak gerçekten hata koşulları için değildir. Nadiren kullanılmalıdır ve sadece "karşılık catchgeleni bulana kadar yığını yukarı taşı " davranışı, yazdığınız bir algoritma için mantıklı olduğunda, ancak throwbir hataya karşılık gelen gibi düşünmenin mantıklı olmadığı durumlarda durum.
Ruby'de yakalama ve fırlatma ne için kullanılır? throw/ catchconstruct'ın güzel kullanımları hakkında bazı önerilerde bulunur .
Aralarındaki somut davranışsal farklılıklar şunları içerir:
rescue FooFooalt sınıfları dahil olmak üzere örnekleri kurtaracak Foo. catch(foo)sadece aynı nesneyiFoo yakalar . Sadece catchörneklerini yakalamak için bir sınıf adı iletmekle kalmaz, aynı zamanda eşitlik karşılaştırmaları bile yapmaz. Örneğin
catch("foo") do
throw "foo"
end
size UncaughtThrowError: uncaught throw "foo"(veya ArgumentError2.2'den önceki Ruby sürümlerinde)
Birden fazla kurtarma maddesi listelenebilir ...
begin
do_something_error_prone
rescue AParticularKindOfError
# Insert heroism here.
rescue
write_to_error_log
raise
end
birden çok catches'in yuvalanması gerekirken ...
catch :foo do
catch :bar do
do_something_that_can_throw_foo_or_bar
end
endÇıplak rescue, rescue StandardErrordeyimsel bir yapıya eşdeğerdir ve bir deyimdir. Bir "çıplak catch", catch() {throw :foo}asla hiçbir şeyi yakalamaz ve kullanılmamalıdır.
gotoiçinde C / C ++ @docwhat sözü var gibi Java gelmiştir mola etiketlenmiş ve devam . (Python'un da bunun için reddedilmiş bir teklifi var .)