diff options
Diffstat (limited to 'lib')
-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. |