------ 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--