------art_3662_14849808.1139806272125
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

This submission:

- passes the tests
- runs a couple orders faster than the continuation generator using
the provided bench
- runs the generator block in a separate thread
- intended to handle both stateful and stateless (functional) generator blocks
- provides a Generator::stateless constructor that allows for the
generator block to run for more than one callback to Generator#yield
- is uncommented

thanks,
Dave

------art_3662_14849808.1139806272125
Content-Type: application/octet-stream; name=my_generator.rb
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ejmb5sks
Content-Disposition: attachment; filename="my_generator.rb"

class MyGenerator

  def self.stateless(enum  il, &block)
    g  ew(enum, &block)
    g.instance_variable_set(:@stateless, true)
    g
  end

  def initialize(enum  il, &block)
    @index  
    @stateless  alse
    if enum
      if enum.respond_to? :to_ary
        @array  num.to_ary
      else
        block  roc { |g| enum.each { |x| g.yield x } }
      end
    elsif block
      @array  rray.new
      @block  lock
      [ :current, :end? ].each do |symbol|
        method  ethod(symbol)
        metaclass.define_method(symbol) { |*args| fill_from_block; method.call(*args) }
      end
    else
      raise ArgumentError, 'Generate nothing?'
    end
  end

  def current
    raise EOFError if spent?
    @array[@index]
  end

  def each(&each_block)
    if @array
      @array.each(&each_block)
    else
      x  bject.new
      def x.yield(value); each_block.call(value); end
      @block.call(x)
    end  
    self
  end

  def end?
    spent?
  end

  attr_reader :index  
  alias_method :pos, :index

  def next
    result  urrent
    @index + 
    result
  end

  def next?
    not end?
  end

  def rewind
    @index  
    if @block
      @array  rray.new if @block
      @thread  ew_fill_thread
    end
    self
  end

  def yield(value)
    @array << value
    Thread.stop unless @stateless
    self
  end

  private

  def spent?
    @index > array.size
  end

  def metaclass
    class << self
      public_class_method :define_method
      self
    end
  end

  def new_fill_thread
    Thread.new { Thread.stop; @block.call(self) }
  end

  def fill_from_block
    return if not spent? or @block_exhausted
    @thread || ew_fill_thread
    return unless @thread.alive?
    @thread.wakeup
    if @stateless
      @block_exhausted  thread.join(1).nil?
    else
      Thread.pass while spent? and @thread.alive?
    end
    @thread.stop unless @thread.stop?
  end

end

------art_3662_14849808.1139806272125--