diff options
| author | KOBAYASHI Shuji <[email protected]> | 2021-02-06 13:28:47 +0900 |
|---|---|---|
| committer | KOBAYASHI Shuji <[email protected]> | 2021-02-06 13:28:47 +0900 |
| commit | 1ea4c512450a79e979b2652764b35a28630f5570 (patch) | |
| tree | 7af5932607dba8bb35a6ef62c01b28afb9e435c3 /mrbgems/mruby-catch | |
| parent | 4bf4650321c540a8abf31aa801afc0e8545571f6 (diff) | |
| download | mruby-1ea4c512450a79e979b2652764b35a28630f5570.tar.gz mruby-1ea4c512450a79e979b2652764b35a28630f5570.zip | |
Make the argument of `Kernel#catch` optional as Ruby does
Also implement the following changes.
* Add tests
* Use `Object#equal?` to compare tags for Ruby compatibility
* Use `attr_reader`
Diffstat (limited to 'mrbgems/mruby-catch')
| -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 |
