diff options
author | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-04-10 10:52:50 +0000 |
---|---|---|
committer | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-04-10 10:52:50 +0000 |
commit | badb86556777cc16d11beb47b38b25997d7aea75 (patch) | |
tree | 3b3e7fe955fd3c737f763d708be8b49d7755cb85 /lib/generator.rb | |
parent | 8202fc3bc37338e2ee4ac2e860b78b1a555f428e (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/generator.rb')
-rw-r--r-- | lib/generator.rb | 38 |
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. |