Skip to content

Instantly share code, notes, and snippets.

@zzak
Created July 27, 2014 21:31
Show Gist options
  • Save zzak/5a18f8d350c114d12a76 to your computer and use it in GitHub Desktop.
Save zzak/5a18f8d350c114d12a76 to your computer and use it in GitHub Desktop.
Index: vm_eval.c
===================================================================
--- vm_eval.c (revision 45094)
+++ vm_eval.c (working copy)
@@ -1767,39 +1767,56 @@
/*
* call-seq:
- * catch([arg]) {|tag| block } -> obj
+ * catch([tag]) {|tag| block } -> obj
*
- * +catch+ executes its block. If a +throw+ is
- * executed, Ruby searches up its stack for a +catch+ block
- * with a tag corresponding to the +throw+'s
- * _tag_. If found, that block is terminated, and
- * +catch+ returns the value given to +throw+. If
- * +throw+ is not called, the block terminates normally, and
- * the value of +catch+ is the value of the last expression
- * evaluated. +catch+ expressions may be nested, and the
- * +throw+ call need not be in lexical scope.
+ * +catch+ executes its block. If +throw+ is not called,
+ * the block executes normally, and +catch+ returns the
+ * value of the last expression evaluated.
*
- * def routine(n)
- * puts n
- * throw :done if n <= 0
- * routine(n-1)
- * end
+ * catch(1) { 123 } # => 123
*
+ * If +throw(tag2, val)+ is called, Ruby searches up its
+ * stack for a +catch+ block whose _tag_ has the same
+ * +object_id+ as _tag2_. If found, the block stops
+ * executing and returns _val_ (or +nil+ if no second
+ * argument was given to +throw+).
*
- * catch(:done) { routine(3) }
+ * catch(1) { throw(1, 456) } # => 456
+ * catch(1) { throw(1) } # => nil
*
- * <em>produces:</em>
+ * When _tag_ is passed as the first argument, +catch+
+ * yields it as the parameter of the block.
*
- * 3
- * 2
- * 1
- * 0
+ * catch(1) {|x| x + 2 } # => 3
*
- * when _arg_ is given, +catch+ yields it as is, or when no
- * _arg_ is given, +catch+ assigns a new unique object to
- * +throw+. this is useful for nested +catch+. _arg_ can
- * be an arbitrary object, not only Symbol.
+ * When no _tag_ is given, +catch+ yields a new unique
+ * object (as from +Object.new+) as the block parameter.
+ * This object can then be used as the argument to
+ * +throw+, and will match the correct +catch+ block.
*
+ * catch do |obj_A|
+ * catch do |obj_B|
+ * throw(obj_B, 123)
+ * puts "This puts is not reached"
+ * end
+ *
+ * puts "This puts is displayed"
+ * 456
+ * end
+ *
+ * # => 456
+ *
+ * catch do |obj_A|
+ * catch do |obj_B|
+ * throw(obj_A, 123)
+ * puts "This puts is still not reached"
+ * end
+ *
+ * puts "Now this puts is also not reached"
+ * 456
+ * end
+ *
+ * # => 123
*/
static VALUE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment