diff options
Diffstat (limited to 'mrbgems')
| -rw-r--r-- | mrbgems/mruby-catch/mrblib/catch.rb | 15 | ||||
| -rw-r--r-- | mrbgems/mruby-catch/test/catch.rb | 79 |
2 files changed, 84 insertions, 10 deletions
diff --git a/mrbgems/mruby-catch/mrblib/catch.rb b/mrbgems/mruby-catch/mrblib/catch.rb index f8dcb3e84..68b165c8d 100644 --- a/mrbgems/mruby-catch/mrblib/catch.rb +++ b/mrbgems/mruby-catch/mrblib/catch.rb @@ -1,22 +1,17 @@ class ThrowCatchJump < Exception + attr_reader :_tag, :_val def initialize(tag, val) - @tag = tag - @val = val + @_tag = tag + @_val = val super("uncaught throw #{tag.inspect}") end - def _tag - @tag - end - def _val - @val - end end module Kernel - def catch(tag, &block) + def catch(tag=Object.new, &block) block.call(tag) rescue ThrowCatchJump => e - unless e._tag == tag + unless e._tag.equal?(tag) raise e end return e._val diff --git a/mrbgems/mruby-catch/test/catch.rb b/mrbgems/mruby-catch/test/catch.rb new file mode 100644 index 000000000..fe5bda096 --- /dev/null +++ b/mrbgems/mruby-catch/test/catch.rb @@ -0,0 +1,79 @@ +assert "return throw value" do + val = ["val"] + result = catch :foo do + loop do + loop do + throw :foo, val + break + end + flunk("should not reach here") + end + false + end + assert_same(val, result) +end + +assert "no throw" do + assert_equal(:foo, catch(:bar){:foo}) +end + +assert "no throw value" do + result = catch :foo do + throw :foo + 1 + end + assert_equal(nil, result) +end + +assert "pass the given tag to block" do + tag = [:foo] + catch(tag){|t| assert_same(tag, t)} +end + +assert "tag identity" do + assert_raise_with_message_pattern(Exception, "uncaught throw *") do + catch [:tag] do + throw [:tag] + end + flunk("should not reach here") + end +end + +assert "without catch arguments" do + result = catch do |tag1| + catch do |tag2| + throw tag1, 1 + flunk("should not reach here 1") + end + flunk("should not reach here 2") + end + assert_equal(1, result) +end + +assert "catches across invocation boundaries" do + v = [] + catch :one do + v << 1 + catch :two do + v << 2 + throw :one + v << 3 + end + v << 4 + end + assert_equal([1,2], v) +end + +assert "catches in the nested invocation with the same key" do + v = [] + catch :tag do + v << 1 + catch :tag do + v << 2 + throw :tag + v << 3 + end + v << 4 + end + assert_equal([1,2,4], v) +end |
