Here's a description of the logic as it currently exists.

Java methods are pulled out of java.lang.Class and stuffed into the
proxy class in arity-specific groups. This means when calling with N
arguments, we only look for methods that take N arguments (hence the
missing varargs support).

If you are passing zero arguments and there's a single zero-argument
method, we call it without further processing. Likewise, if you are
calling with N arguments and there's only one N-argument overload, we
call that one and hope the types will coerce. This is also a source of
bad error messages, like "expected [java.lang.String], got:
[org.jruby.RubyFixnum]" which aren't very helpful.

When coercing, we call JavaUtil.convertArgumentToType, which is
*almost* the "to_java" in the new specification. It takes
ThreadContext, IRubyObject, and Class, where the Class is the target
Java type we want to try to convert to. convertArgumentToType has
several pieces of logic:

* If the argument is a JavaObject (the inner wrapper type) it tries to
coerce the value it wraps with coerceJavaObjectToType, which tries to
do a duck-typed conversion of procs to interfaces, or else just leaves
it as a JavaObject
* If the argument is a JavaProxy (the concrete supertype for all
wrapped Java objects in Ruby-land) it uses the real Java object it
wraps (without checking if it is of the appropriate type)
* If the argument's dataWrapStruct is a JavaObject, it uses the
unwrapped value without futher processing (differing from the first
JavaObject case above)
* Otherwise, it falls back on a hardcoded set of coercions for core types

The hardcoded coercion logic uses arg.getMetaClass().index
(ClassIndex) as follows:

* for NilClass, use the result of coerceNilToType
* for Fixnum, Bignum, and Float, use getNumericConverter(target
class).coerce(arg, target)
* for String, use coerceStringToType
* for TrueClass, return Boolean.TRUE
* for FalseClass, return Boolean.FALSE
* for Time, return ((RubyTime)arg).getJavaDate()
* for all others, call coerceOtherToType

The coerceOtherToType method tries to do a duck-typing conversion of
procs to interface impls, and otherwise tries to call to_java_object.

In short, it's a big old mess. All this basically fits into the new
logic, but it's sprinkled all over the codebase. That makes it harder
to unravel and recompose it with the new protocol, but it needs to be
done anyway...

- Charlie

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to