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