summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authorknu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-04-10 10:52:50 +0000
committerknu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-04-10 10:52:50 +0000
commitbadb86556777cc16d11beb47b38b25997d7aea75 (patch)
tree3b3e7fe955fd3c737f763d708be8b49d7755cb85 /eval.c
parent8202fc3bc37338e2ee4ac2e860b78b1a555f428e (diff)
* enumerator.c (rb_eStopIteration), eval.c (rb_f_loop), ruby.h:
Add a new exception class StopIteration, which breaks Kernel#loop iteration when raised; backported from 1.9. * enumerator.c (enumerator_next, enumerator_rewind): Implement #next and #rewind using the "generator" library. * lib/generator.rb: Implement Enumerable::Enumerator#next and #rewind. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@15954 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/eval.c b/eval.c
index 8972f3bd72..5a03eccc91 100644
--- a/eval.c
+++ b/eval.c
@@ -5157,6 +5157,16 @@ rb_yield_splat(values)
return rb_yield_0(values, 0, 0, 0, avalue);
}
+static VALUE
+loop_i()
+{
+ for (;;) {
+ rb_yield_0(Qundef, 0, 0, 0, Qfalse);
+ CHECK_INTS;
+ }
+ return Qnil;
+}
+
/*
* call-seq:
* loop {|| block }
@@ -5169,15 +5179,14 @@ rb_yield_splat(values)
* break if !line or line =~ /^qQ/
* # ...
* end
+ *
+ * StopIteration raised in the block breaks the loop.
*/
static VALUE
rb_f_loop()
{
- for (;;) {
- rb_yield_0(Qundef, 0, 0, 0, Qfalse);
- CHECK_INTS;
- }
+ rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
return Qnil; /* dummy */
}