Skip to content

Commit

Permalink
Implemented Enumerator#peek for 1.9
Browse files Browse the repository at this point in the history
  • Loading branch information
jtdowney committed Oct 23, 2011
1 parent 71098f6 commit f256fda
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 39 deletions.
34 changes: 0 additions & 34 deletions kernel/common/enumerator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 if Rubinius.ruby18?

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.
Expand Down
37 changes: 37 additions & 0 deletions kernel/common/enumerator18.rb
Original file line number Diff line number Diff line change
@@ -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
42 changes: 42 additions & 0 deletions kernel/common/enumerator19.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions kernel/common/load_order18.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module18.rbc
enumerable.rbc
enumerable18.rbc
enumerator.rbc
enumerator18.rbc
argf.rbc
argf18.rbc
tuple.rbc
Expand Down
5 changes: 0 additions & 5 deletions spec/tags/19/ruby/core/enumerator/peek_tags.txt

This file was deleted.

0 comments on commit f256fda

Please sign in to comment.