您可以在块中引发异常并捕获该异常。
module Tester
class Breaker < Exception; end
class GoodBreak < Breaker; end
class BaadBreak < Breaker; end
end
def test_block(name)
begin
yield
rescue Tester::Breaker=>e
case e
when Tester::GoodBreak then puts "All is well with #{name}"
when Tester::BaadBreak then puts "BAD STUFF WITH #{name}"
else raise
end
end
end
def good; raise Tester::GoodBreak; end
def bad; raise Tester::BaadBreak; end
test_block('early out') do
good if true
good if puts("NEVER SEE THIS") || true
bad
end
test_block('simple pass') do
good if false
good if puts("SEE THIS FROM PASS TEST") || true
bad
end
test_block('final fail') do
good if false
good if puts("SEE THIS BUT PUTS IS NIL")
bad
end
#=> All is well with early out
#=> SEE THIS FROM PASS TEST
#=> All is well with simple pass
#=> SEE THIS BUT PUTS IS NIL
#=> BAD STUFF WITH final fail
下面是另一个使用
throw/catch
(谢谢@jledev!)而不是
raise/rescue
(更新后传递返回值):
def test_block(name)
result = catch(:good){ catch(:bad){ yield } }
puts "Testing #{name} yielded '#{result}'", ""
end
def good; throw :good, :good; end
def bad; throw :bad, :bad; end
test_block('early out') do
good if true
good if puts("NEVER SEE THIS") || true
bad
end
test_block('simple pass') do
good if false
good if puts("SEE THIS FROM PASS TEST") || true
bad
end
test_block('final fail') do
good if false
good if puts("SEE THIS BUT PUTS IS NIL")
bad
end
#=> Testing early out yielded 'good'
#=>
#=> SEE THIS FROM PASS TEST
#=> Testing simple pass yielded 'good'
#=>
#=> SEE THIS BUT PUTS IS NIL
#=> Testing final fail yielded 'bad'