Object
Generator converts an internal iterator (i.e. an Enumerable object) to an external iterator.
Note that it is not very fast since it is implemented using continuations, which are currently slow.
require 'generator' # Generator from an Enumerable object g = Generator.new(['A', 'B', 'C', 'Z']) while g.next? puts g.next end # Generator from a block g = Generator.new { |g| for i in 'A'..'C' g.yield i end g.yield 'Z' } # The same result as above while g.next? puts g.next end
Creates a new generator either from an Enumerable object or from a block.
In the former, block is ignored even if given.
In the latter, the given block is called with the generator itself, and
expected to call the yield method for each element.
# File generator.rb, line 69
def initialize(enum = nil, &block)
if enum
@block = proc { |g|
enum.each { |x| g.yield x }
}
else
@block = block
end
@index = 0
@queue = []
@cont_next = @cont_yield = @cont_endp = nil
if @cont_next = callcc { |c| c }
@block.call(self)
@cont_endp.call(nil) if @cont_endp
end
self
end
Returns the element at the current position.
# File generator.rb, line 141
def current()
if @queue.empty?
raise EOFError, "no more elements available"
end
@queue.first
end
Rewinds the generator and enumerates the elements.
# File generator.rb, line 157
def each
rewind
until end?
yield self.next
end
self
end
Returns true if the generator has reached the end.
# File generator.rb, line 102
def end?()
if @cont_endp = callcc { |c| c }
@cont_yield.nil? && @queue.empty?
else
@queue.empty?
end
end
Returns the current index (position) counting from zero.
# File generator.rb, line 116
def index()
@index
end
Returns the element at the current position and moves forward.
# File generator.rb, line 126
def next()
if end?
raise EOFError, "no more elements available"
end
if @cont_next = callcc { |c| c }
@cont_yield.call(nil) if @cont_yield
end
@index += 1
@queue.shift
end
Returns true if the generator has not reached the end yet.
# File generator.rb, line 111
def next?()
!end?
end
Returns the current index (position) counting from zero.
# File generator.rb, line 121
def pos()
@index
end