Generator implementation


#1

I was reading the Generator implementation a few hours ago,
finding out that it’s a little hard to understand the code for me.
Then I started writing my own implementation with Continuation,
hoping I understood things well. Did it have to be that complex?

The result was shown below, and they passed the unit tests in
generator.rb.
I believed they are faster than the original implementation,
(p.s. generator.rb,v 1.2.2.2 2004/05/07 08:48:23 matz Exp $)
but was not sure if there’s something wrong.
Maybe there’s more consideration I didn’t notice before.
Please correct me if I lost something. Thank you.

And if you thought this implementation was useful, feel free to use it
under the same terms as Ruby.

class Generator
include Enumerable
def initialize enum = nil, &block
if enum
@block = lambda{|g| enum.each{|i| g.yield i}}
else
@block = block
end
@index = 0
@value = nil
if @con_next = callcc{|c|c}
@block.call self
@con_next.call
end
end

def next
    raise EOFError, "no more elements available" if end?
    @index += 1
    result = @value
    @con_yield.call if @con_next = callcc{|c|c}
    result
end

def yield value
    @value = value
    @con_next.call if @con_yield = callcc{|c|c}
end

def next?
    return true if @con_yield
    return false
end
def end?
    !next?
end
def index
    @index
end
alias_method :pos, :index
def current
    raise EOFError, "no more elements available" unless @value
    @value
end
def rewind
    initialize &@block
    self
end
def each
    rewind
    yield(self.next) while self.next?
    self
end

end

Thank you for reading.