I'm implementing some Ruby classes/modules in Java, but have run up against
a problem trying to call #super from Java-implemented Ruby methods.
Specifically, I'm hitting problems trying to chain #initialize methods, but
I imagine I'd encounter the same problem with other methods.  I've dug
through the code base but haven't found any good examples for what I'm
trying to accomplish.  I figured someone here (Charlie? Tom? Ola?) might
have an answer.

Here's what I've got:

# Ruby version of module A
module A
  def initialize(a, &block)
     super() # no args
    #...
  end
end

# Ruby version of module B
module B # implemented in Java
  include A
  def initialize(a, b, &block)
    super(a, &block)
    #...
  end
end

class C
  include B
  # no initialize defined
end

class D < C
  def initialize(a, b, c, &block)
    super(a, b, &block)
  end
end

# Java version of module A
RubyModule moduleA = runtime.defineModule("A");
//...
moduleA.defineMethod("initialize", callbackFactory.getOptSingletonMethod
("initialize"));

public static IRubyObject initialize(
       IRubyObject self,
       IRubyObject[] args,
       Block block) {
    //...
    self.callSuper(runtime.getThreadContext(), IRubyObject.NULL_ARRAY,
Block.NULL_BLOCK);
}

# Java version of module B
RubyModule moduleB = runtime.defineModule("B");
moduleB.includeModule(moduleA);
//...
moduleB.defineMethod("initialize", callbackFactory.getOptSingletonMethod
("initialize"));

public static IRubyObject initialize(
       IRubyObject self,
       IRubyObject[] args,
       Block block) {
    //...
    IRubyObject[] sargs = new IRubyObject[] { args[1] };
    self.callSuper(runtime.getThreadContext(), sargs, block);
}

What happens is that the Java version of module B's initialize ends up
calling itself (indirectly).  I tracked the calls into RubyObject#callSuper
for both the Ruby and Java versions, and it appears that I need to use a
different ThreadContext (the Ruby version shows up with a different
tc.getFrameKlazz() value than the Java version).  But I haven't been able to
figure out how to get to the right one. (Or the problem could be with the
way I include A into B, but apart from calling super, everything appears to
work correctly.)  Any ideas?

Thanks,

-Bill

Reply via email to