Bug in the voodoo magic

Posted by Ceaser Larry on September 8, 2006

I finally found a way to reproduce the “method called on a terminated object” problem I was having with RubyCLR. It appears that reference objects that are marshaled from the CLR to a Ruby object through an interface are terminated before you can use them. Any attempt to use these terminated objects will occasionally cause a runtime error.

I’m using an array of hashes to re-create a result set with column names. I use a Ruby proxy object to create Ruby Array, Hash, Date and Time objects and to get around RubyCLR’s object identity problems. This also insures that only native Ruby objects are used to represent the data from the database.

I’ve submitted a ticket to RubyForge, but hope I can understand how the bridge works with interfaces before this weekend is over.

Code to Reproduce the error

require 'rubyclr'

self.class.inline do |c|
c.compile <<-EOL
  using System;
  namespace Example {
    public interface IProxy {
      void Store(string name, string value);
    }

    public class Generator
    {
      private IProxy m_Proxy;
      public Generator(IProxy proxy)
      {
        m_Proxy = proxy;
      }

      public void SendToProxy()
      {
        m_Proxy.Store(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
      }
    }
  }
  EOL
end

class RubyProxy
  implements Example::IProxy

  def initialize
    @values = {}
  end

  def store(name, value)
    @values.store(name, value)
    nil
  end

  def reset
    @values = {}
  end
end

proxy = RubyProxy.new
generator = Example::Generator.new(proxy)
count = 0
while(true)
  count = count + 1000
  i = 0
  print "Sending #{count} values..."
  while(i < count)
    generator.send_to_proxy
    i = i + 1
  end
  puts "dereference collection"
  proxy.reset
end