summaryrefslogtreecommitdiff
path: root/enumerator.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 /enumerator.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 'enumerator.c')
-rw-r--r--enumerator.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/enumerator.c b/enumerator.c
index e5bf538f0c..fefbc28b34 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -23,6 +23,8 @@
VALUE rb_cEnumerator;
static VALUE sym_each, sym_call;
+VALUE rb_eStopIteration;
+
static VALUE
proc_call(proc, args)
VALUE proc;
@@ -387,6 +389,45 @@ enumerator_with_index(obj)
enumerator_with_index_i, (VALUE)&memo);
}
+/*
+ * call-seq:
+ * e.next => object
+ *
+ * Returns the next object in the enumerator, and move the internal
+ * position forward. When the position reached at the end, internal
+ * position is rewinded then StopIteration is raised.
+ *
+ * Note that enumeration sequence by next method does not affect other
+ * non-external enumeration methods, unless underlying iteration
+ * methods itself has side-effect, e.g. IO#each_line.
+ *
+ * Caution: Calling this method causes the "generator" library to be
+ * loaded.
+ */
+
+static VALUE
+enumerator_next(obj)
+ VALUE obj;
+{
+ rb_require("generator");
+ return rb_funcall(obj, rb_intern("next"), 0, 0);
+}
+
+/*
+ * call-seq:
+ * e.rewind => e
+ *
+ * Rewinds the enumeration sequence by the next method.
+ */
+
+static VALUE
+enumerator_rewind(obj)
+ VALUE obj;
+{
+ rb_require("generator");
+ return rb_funcall(obj, rb_intern("rewind"), 0, 0);
+}
+
void
Init_Enumerator()
{
@@ -406,6 +447,10 @@ Init_Enumerator()
rb_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1);
rb_define_method(rb_cEnumerator, "each", enumerator_each, 0);
rb_define_method(rb_cEnumerator, "with_index", enumerator_with_index, 0);
+ rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
+ rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
+
+ rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
sym_each = ID2SYM(rb_intern("each"));
sym_call = ID2SYM(rb_intern("call"));