L
Lin Jen-Shin
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 os, :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.
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 os, :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.