summaryrefslogtreecommitdiff
path: root/lib
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 /lib
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 'lib')
-rw-r--r--lib/generator.rb38
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/generator.rb b/lib/generator.rb
index a010559b60..dbdd0f40a9 100644
--- a/lib/generator.rb
+++ b/lib/generator.rb
@@ -165,6 +165,44 @@ class Generator
end
end
+class Enumerable::Enumerator
+ def __generator
+ @generator ||= Generator.new(self)
+ end
+ private :__generator
+
+ # 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: This feature internally uses Generator, which uses callcc
+ # to stop and resume enumeration to fetch each value. Use with care
+ # and be aware of the performance loss.
+ def next
+ g = __generator
+ return g.next unless g.end?
+
+ g.rewind
+ raise StopIteration, 'iteration reached at end'
+ end
+
+ # call-seq:
+ # e.rewind => e
+ #
+ # Rewinds the enumeration sequence by the next method.
+ def rewind
+ __generator.rewind
+ self
+ end
+end
+
#
# SyncEnumerator creates an Enumerable object from multiple Enumerable
# objects and enumerates them synchronously.