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

On 2/14/06, Ross Bamford <rossrt / roscopeco.co.uk> wrote:
> ###### Supporting infinite iterators but *not* realtime. #####
>
> ### TESTING: davelee_generator.rb
> Loaded suite tests
> Started
> ....E
> Finished in 1.075006 seconds.
>
>   1) Error:
> test_realtime(TC_TGenerator):
> NoMethodError: undefined method `size' for nil:NilClass
>     ./davelee_generator.rb:82:in `spent?'
>     ./davelee_generator.rb:32:in `current'
>     ./davelee_generator.rb:55:in `next'
>     tests.rb:179:in `test_realtime'
>     tests.rb:177:in `test_realtime'
>     tests.rb:174:in `test_realtime'
>
> 5 tests, 1557 assertions, 0 failures, 1 errors

As James said, thanks for doing this Ross.

I hadn't added test_realtime to my test set, but now I have and this
bug is fixed.  I have attached the fixed version for anyone who cares.
 For the hell of it, I also optimized by manually inlining some method
calls, and eliminating redundant bounds checking.  This should now
pass all tests and run much faster.

These are basically the optimizations:

   def current
-    raise EOFError if spent?
-    @array[@index]
+    @array.fetch(@index) rescue raise EOFError
   end

   def end?
-    spent?
+    @index >= @array.size
   end

   def next
-    result = current
+    begin
+      result = @array.fetch(@index)
+    rescue
+      raise EOFError
+    end
     @index += 1
     result
   end

   def next?
-    not end?
+    @index < @array.size
   end


Dave

------art_604_32898385.1139939660769
Content-Type: application/octet-stream; name=my_generator.rb
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ejoijxq3
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
    end
    if block
      @array  rray.new
      @block  lock
      [ :current, :end?, :next?, :next ].each do |symbol|
        method  ethod(symbol)
        metaclass.define_method(symbol) { |*args| fill_from_block; method.call(*args) }
      end
    end
    raise ArgumentError, 'Generate nothing?' unless @array
  end

  def current
    @array.fetch(@index) rescue raise EOFError
  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?
    @index > array.size
  end

  attr_reader :index  
  alias_method :pos, :index

  def next
    begin
      result  array.fetch(@index)
    rescue
      raise EOFError
    end
    @index + 
    result
  end

  def next?
    @index < @array.size
  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_604_32898385.1139939660769
Content-Type: text/plain; name=my_generator.diff.txt; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ejoika4l
Content-Disposition: attachment; filename="my_generator.diff.txt"

--- orig_my_generator.rb	2006-02-14 11:42:28.646227994 -0600
+++ my_generator.rb	2006-02-14 11:48:14.338112433 -0600
@@ -15,21 +15,20 @@
       else
         block  roc { |g| enum.each { |x| g.yield x } }
       end
-    elsif block
+    end
+    if block
       @array  rray.new
       @block  lock
-      [ :current, :end? ].each do |symbol|
+      [ :current, :end?, :next?, :next ].each do |symbol|
         method  ethod(symbol)
         metaclass.define_method(symbol) { |*args| fill_from_block; method.call(*args) }
       end
-    else
-      raise ArgumentError, 'Generate nothing?'
     end
+    raise ArgumentError, 'Generate nothing?' unless @array
   end
 
   def current
-    raise EOFError if spent?
-    @array[@index]
+    @array.fetch(@index) rescue raise EOFError
   end
 
   def each(&each_block)
@@ -44,20 +43,24 @@
   end
 
   def end?
-    spent?
+    @index > array.size
   end
 
   attr_reader :index  
   alias_method :pos, :index
 
   def next
-    result  urrent
+    begin
+      result  array.fetch(@index)
+    rescue
+      raise EOFError
+    end
     @index + 
     result
   end
 
   def next?
-    not end?
+    @index < @array.size
   end
 
   def rewind
@@ -106,4 +109,3 @@
   end
 
 end
-

------art_604_32898385.1139939660769--