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. throw
değil. Bir döngüden çıkmak için throw
kullanmayı düşünün goto
.
raise
, fail
, rescue
Ve ensure
sap hataları olarak da bilinen istisnalarthrow
ve catch
vardı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 while
dö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
/ catch
construct'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 .raise
except
throw
raise
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 catch
geleni bulana kadar yığını yukarı taşı " davranışı, yazdığınız bir algoritma için mantıklı olduğunda, ancak throw
bir 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
/ catch
construct'ın güzel kullanımları hakkında bazı önerilerde bulunur .
Aralarındaki somut davranışsal farklılıklar şunları içerir:
rescue Foo
Foo
alt 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 ArgumentError
2.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 catch
es'in yuvalanması gerekirken ...
catch :foo do
catch :bar do
do_something_that_can_throw_foo_or_bar
end
end
Çıplak rescue
, rescue StandardError
deyimsel 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.
goto
iç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 .)