On 24 Aug 2001, at 7:03, Brian Marick wrote:

> At 03:18 AM 8/23/01, you wrote:
> >I'd still like to find a way to suspend an arbitrary computation, get
> >a "resumer" that can be passed around and called anywhere to return
> >the next value.

> ( class LazyComputation skipped )

Hi Brian,

thanks for the code. I like it. It looks very much like my Iterator 
class, which I needed to traverse multiple Enumerables in parallel. I 
wanted to publish it some months ago, but never took the time to 
actually do so.

Now that you've come up independently with a similar structure, it 
seems that this is the "right" way to interrupt a computation and 
continue it from the outside.

Just in case you're curious here's the Iterator class (the name 
comes from the Java Iterator interface).


class Iterator

  public
  
  attr_reader :enumerable, :has_next
  
  def initialize( enumerable, end_value = nil, &end_block )
    @enumerable = enumerable
    @end_value = end_value
    @end_block = end_block
    initialize_fetch_block
  end
  
  def next
    @has_next ? fetch_next_element : fetch_end_value
  end

  def rewind
    initialize_fetch_block
    self
  end
  
  
  protected
  
  def initialize_fetch_block
    callcc do | @after_fetch |
      @has_next = true
      @enumerable.each do | @next_element |
        callcc do | @next_fetch | @after_fetch.call end
      end
      @has_next = false
      @next_fetch = nil
      @after_fetch.call
    end
    @after_fetch = nil
  end

  def fetch_next_element
    result = @next_element
    callcc do | @after_fetch | @next_fetch.call end
    @after_fetch = nil
    result
  end

  def fetch_end_value
    @end_block ? @end_block.call : @end_value
  end
  
end


If somebody needs to traverse multiple enumerables in parallel and 
doesn't want to use matz's solution in the FAQ which uses threads 
then write me and I'll finally take the time to publish the code.

Pit