summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2020-08-28 17:49:27 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2020-10-12 18:20:07 +0900
commit7eaaee5405f71c598893e9a022c755f61f11e9ec (patch)
tree031900b5407f92f8c88c6917625340d81a62af76
parent471479e723157c1a7df2023ab2eea24fa4ca2246 (diff)
downloadmruby-7eaaee5405f71c598893e9a022c755f61f11e9ec.tar.gz
mruby-7eaaee5405f71c598893e9a022c755f61f11e9ec.zip
Add a new gem: `mruby-catch`.
Implements `catch`/`throw` non-local jump inherited from Lisp. `catch([tag]) {|tag| block } -> obj` Example: ``` catch(:foo) { 123 } # => 123 catch(:foo) { throw(:foo, 456) } # => 456 catch(:foo) { throw(:foo) } # => nil ```
-rw-r--r--mrbgems/mruby-catch/mrbgem.rake5
-rw-r--r--mrbgems/mruby-catch/mrblib/catch.rb27
2 files changed, 32 insertions, 0 deletions
diff --git a/mrbgems/mruby-catch/mrbgem.rake b/mrbgems/mruby-catch/mrbgem.rake
new file mode 100644
index 000000000..c714d443d
--- /dev/null
+++ b/mrbgems/mruby-catch/mrbgem.rake
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-catch') do |spec|
+ spec.license = 'MIT'
+ spec.author = 'mruby developers'
+ spec.summary = 'Catch / Throw non-local Jump'
+end
diff --git a/mrbgems/mruby-catch/mrblib/catch.rb b/mrbgems/mruby-catch/mrblib/catch.rb
new file mode 100644
index 000000000..89eedf66a
--- /dev/null
+++ b/mrbgems/mruby-catch/mrblib/catch.rb
@@ -0,0 +1,27 @@
+class ThrowCatchJump < Exception
+ def initialize(tag, val)
+ @tag = tag
+ @val = val
+ super("uncaught throw :#{tag}")
+ end
+ def _tag
+ @tag
+ end
+ def _val
+ @val
+ end
+end
+
+module Kernel
+ def catch(tag, &block)
+ block.call(tag)
+ rescue ThrowCatchJump => e
+ unless e._tag == tag
+ raise e
+ end
+ return e._val
+ end
+ def throw(tag, val=nil)
+ raise ThrowCatchJump.new(tag, val)
+ end
+end