Tom recently filed an issue for a feature we've wanted: to have the modules associated with Java interfaces also contain the methods from those interfaces.
Currently, if you list the methods on an interface module, you won't see any of the Java interfaces methods. This makes it difficult to use meta-programming on those interfaces, either by adding default stubs or by inspecting the methods a given interface has. So I started by making the naive change to just go ahead and bind the methods, but I ran into a chicken/egg problem (probably the same problem I ran into when I tried this years ago). Say we have this interface: public interface DoIt { public void doIt(); } We can implement this in Ruby using either "doIt" or "do_it", the latter by popular demand some years ago. If we use "do_it", we run into a problem with my changes. The current interface implementation logic basically just defines in the new class a "doIt" Java method that redispatches to "doIt" and "do_it" in Ruby in turn. That way, if you don't define a Ruby "doIt" but you do define "do_it", the Java "doIt" will eventually call your "do_it" Ruby code. If, as in my current patch, the interface modules actually bind the methods associated with them, the behind-the-scenes redispatch inside the interface-impl "doIt" *does* find a Ruby "doIt" method...the stub we bound into the module. So you have this: Pre-patch: * Java calls "doIt" * Interface impl of "doIt" searches the Ruby class for "doIt" and "do_it" in turn * Eventually it finds "do_it" because there's no "doIt" defined in Ruby * "do_it" is called in Ruby Post-patch: * Java calls "doIt" * Interface impl of "doIt" searches the Ruby class for "doIt" and "do_it" in turn * It finds the Ruby "doIt" we bound into the interface module * The bound "doIt" assumes we're calling a Java class, and reflectively dispatches to the Java "doIt" * Lather, rinse, and repeat" It blows the stack, because the Java version of "doIt" wants to call the Ruby version of "doIt", and the Ruby version of "doIt" wants to call the Java version. I'm pondering how to get around this. There's a few options that aren't great: * Make the interface module version of the method do the same search for all names, but have it explicitly ignore module methods. This would break including a Ruby module to provide the bodies of Java interface methods (and might be tricky anyway). * When implementing a Java interface method using a different name, always also reimplement the real name. This might be hard to figure out, since the odd names will look like normal Ruby methods. * Have the generated interface impl look for the real name *last*, allowing Ruby names to take priority. This might work, but it would change lookup order (but they're cached, so it wouldn't impact perf). I'm going to try the third option, but I'm open to other suggestions. - Charlie --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email