Callcc problem in Generator

Discussion in 'Ruby' started by Greg Fitzgerald, Jan 25, 2005.

  1. Hey all,

    I was playing with the Generator class the other day and decided I
    didn't like that you can't break out while iterating through the
    generator without first having already taken the time to iterate to
    the element after the one you were at when you decided to break out.

    The following code shows what I mean. It runs through
    test_generator() twice, the first with the current implementation of
    Generator, and the second with a new one I whipped up. It shows that
    the current implementation takes longer to execute when breaking out
    early. Also, outside of performance, I don't like that if I were
    reading a stream of data and decided to break out, it would read one
    too many lines--kind of an ugly side-effect.

    Unfortunately, there's a significant bug in my version that I been
    trying to crack all night and I can't figure it out for the life of
    me. I want to be able to start iterating, then midway through, call
    rewind(), and then start iterating through again. When I do that, it
    leaves the stack in an odd place, and when I call each(), it will make
    it all the way to the end then get caught in an infinite loop inside
    next?().

    So I guess my question is, if you create a continuation with callcc()
    and then decide never to call that continuation, is there some way to
    unwind the stack?

    Thanks,
    Greg



    require 'generator'

    def test_generator()
    timeStart = Time.now
    puts "start constructing at #{Time.now - timeStart}"
    gen = Generator.new do |g|
    for num in [1,2,3,4,5]
    sleep(3)
    g.yield(num)
    end
    end

    puts "finished constructing at #{Time.now - timeStart}"

    puts "getting first element at #{Time.now - timeStart}"
    for num in gen
    puts num
    break if num == 3
    puts "getting next element at #{Time.now - timeStart}"
    end
    puts "done at #{Time.now - timeStart}"

    puts "\n\n"
    end

    puts "Ruby's Generator"
    test_generator()

    class EndOfGenerator < Exception
    end

    class Generator
    def initialize(&closure)
    @closure = closure
    return rewind()
    end

    def each()
    rewind()

    while self.next?()
    yield self.next()
    end
    return self
    end

    def rewind()
    @closureEntryPoint = nil
    @currentElement = nil
    @nextElement = nil
    @position = -1
    #self.next?()
    return self
    end

    def pos()
    return @position
    end

    def current()
    if @currentElement == nil
    begin
    self.next()
    @nextElement = @currentElement
    rescue EndOfGenerator
    end
    end

    return @currentElement
    end

    def next?()
    return true if @nextElement
    begin
    @nextElement = self.next()
    return true
    rescue EndOfGenerator
    return false
    end
    end

    def end?()
    return !self.next?()
    end

    def next()
    if @nextElement
    @currentElement = @nextElement
    else
    @currentElement = callcc do |cc|
    @generatorEntryPoint = cc
    if @closureEntryPoint == nil
    @closure.call(self)
    raise EndOfGenerator.new()
    else
    @closureEntryPoint.call()
    end
    end
    @position += 1
    end
    @nextElement = nil
    return @currentElement
    end

    def yield(obj)
    return callcc do |cc|
    @closureEntryPoint = cc
    @generatorEntryPoint.call(obj)
    end
    end
    end

    puts "Corrected generator"
    test_generator()
     
    Greg Fitzgerald, Jan 25, 2005
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jim Bob

    Why does Ruby have callcc?

    Jim Bob, Aug 6, 2003, in forum: Ruby
    Replies:
    22
    Views:
    249
  2. zuzu
    Replies:
    14
    Views:
    245
    Phil Tomson
    Aug 23, 2004
  3. Mikael Brockman
    Replies:
    2
    Views:
    141
    Mikael Brockman
    Sep 25, 2004
  4. Bill Atkins

    callcc Semantics

    Bill Atkins, Oct 18, 2004, in forum: Ruby
    Replies:
    2
    Views:
    109
    Eric Hodel
    Oct 19, 2004
  5. mepython
    Replies:
    0
    Views:
    128
    mepython
    Mar 3, 2005
Loading...

Share This Page