Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #1345 from jtdowney/enumerator-next-impl

Implemented Enumerator#peek for 1.9 and fixed a failure for Enumerator#next
  • Loading branch information...
commit 019f146b074864aac8897816d712916dc25a82a0 2 parents fedd69b + f256fda
@rue rue authored
View
34 kernel/common/enumerator.rb
@@ -159,40 +159,6 @@ def reset
end
end
- # Returns the next object in the enumerator
- # and move the internal position forward.
- # When the position reached at the end,
- # internal position is rewound 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.
- #
- def next
- unless @generator
- # Allow #to_generator to return nil, indicating it has none for
- # this method.
- if @object.respond_to? :to_generator
- @generator = @object.to_generator(@iter)
- end
-
- if !@generator and gen = FiberGenerator
- @generator = gen.new(self)
- else
- @generator = ThreadGenerator.new(self, @object, @iter, @args)
- end
- end
-
- begin
- return @generator.next if @generator.next?
- rescue StopIteration
- end
-
- @generator.rewind
-
- raise StopIteration, "iteration reached end"
- end
-
# Rewinds the enumeration sequence by the next method.
#
# If the enclosed object responds to a "rewind" method, it is called.
View
37 kernel/common/enumerator18.rb
@@ -0,0 +1,37 @@
+module Enumerable
+ class Enumerator
+ # Returns the next object in the enumerator
+ # and move the internal position forward.
+ # When the position reached at the end,
+ # internal position is rewound 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.
+ #
+ def next
+ unless @generator
+ # Allow #to_generator to return nil, indicating it has none for
+ # this method.
+ if @object.respond_to? :to_generator
+ @generator = @object.to_generator(@iter)
+ end
+
+ if !@generator and gen = FiberGenerator
+ @generator = gen.new(self)
+ else
+ @generator = ThreadGenerator.new(self, @object, @iter, @args)
+ end
+ end
+
+ begin
+ return @generator.next if @generator.next?
+ rescue StopIteration
+ end
+
+ @generator.rewind
+
+ raise StopIteration, "iteration reached end"
+ end
+ end
+end
View
42 kernel/common/enumerator19.rb
@@ -13,6 +13,7 @@ def initialize(obj=undefined, iter=:each, *args, &block)
@iter = iter.to_sym
@args = args
@generator = nil
+ @lookahead = []
end
def with_index(offset=0)
@@ -31,6 +32,47 @@ def with_index(offset=0)
end
end
+ # Returns the next object in the enumerator
+ # and move the internal position forward.
+ # When the position reached at the end,
+ # internal position is rewound 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.
+ #
+ def next
+ return @lookahead.shift unless @lookahead.empty?
+
+ unless @generator
+ # Allow #to_generator to return nil, indicating it has none for
+ # this method.
+ if @object.respond_to? :to_generator
+ @generator = @object.to_generator(@iter)
+ end
+
+ if !@generator and gen = FiberGenerator
+ @generator = gen.new(self)
+ else
+ @generator = ThreadGenerator.new(self, @object, @iter, @args)
+ end
+ end
+
+ begin
+ return @generator.next if @generator.next?
+ rescue StopIteration
+ end
+
+ raise StopIteration, "iteration reached end"
+ end
+
+ def peek
+ return @lookahead.first unless @lookahead.empty?
+ item = self.next
+ @lookahead << item
+ item
+ end
+
# A supporting class for Enumerator that allows for easy proxying to a Generator's yield.
class Yielder
def initialize(&block)
View
1  kernel/common/load_order18.txt
@@ -7,6 +7,7 @@ module18.rbc
enumerable.rbc
enumerable18.rbc
enumerator.rbc
+enumerator18.rbc
argf.rbc
argf18.rbc
tuple.rbc
View
1  spec/tags/19/ruby/core/enumerator/next_tags.txt
@@ -1 +0,0 @@
-fails:Enumerator#next cannot be called again until the enumerator is rewound
View
5 spec/tags/19/ruby/core/enumerator/peek_tags.txt
@@ -1,5 +0,0 @@
-fails:Enumerator#peek returns the next element in self
-fails:Enumerator#peek does not advance the position of the current element
-fails:Enumerator#peek can be called repeatedly without advancing the position of the current element
-fails:Enumerator#peek works in concert with #rewind
-fails:Enumerator#peek raises StopIteration if called on a finished enumerator
Please sign in to comment.
Something went wrong with that request. Please try again.