On Mon, Sep 21, 2009 at 12:37 PM, Charles Oliver Nutter
<[email protected]> wrote:
> Introducing 'coerce_to?'
>
> In order to reconcile this twist, all coercible classes will implement
> a coerce_to? method that takes a target Java type and returns a
> numeric score for the coercion to that type. The score's scale has not
> been decided, but for discussion purposes we'll consider 0-10 where 0
> means "I can't coerce to that" and 10 means "that is my ideal coercion
> target". In the case of Fixnum, the "ideal" target would be to do no
> coercion at all and pass RubyFixnum as-is to the target method. This
> would allow calling APIs that accept JRuby types directly, which is
> not possible now. It would also change calling Object targets to pass
> RubyFixnum as well; this is a potentially breaking change, so we
> should discuss it. Fixnum also has other targets that are "natural"
> conversions like int or Long. Additional coercion targets can be added
> to any type's coerce_to? method, as long as you also add logic to
> another method: to_java.
Let me clarify. There are two types of variables when users use JRuby:
Java originated variables used in Ruby, and Ruby originated variables
used in Java. The new coerce_to? method is for the latter one, Ruby
originated variables used in Java, right? Currently, JRuby Embed uses
JavaEmbedUtils#rubyToJava method to convert types of all variables
used in Ruby so that Java program can use those in it. Will the
coerce_to? affect rubyToJava method?
> Types from Java will not auto-coerce
>
> In order to allow users to pre-coerce objects and to defer coercing
> back to Ruby types, most return values will not coerce automatically
> anymore. Values coming back as int or Int or Long, etc, will remain as
> their Java types. Calling to_int or to_i or similar Ruby coercion
> methods will coerce them back into Fixnum or Float, but it won't
> happen automatically. Since most APIs that require a Fixnum attempt to
> do a conversion already, either through to_i or to_int, this should
> allow most APIs to continue to work just fine. The reason for ending
> this auto-coercion is simple: it allows you to control that coercion
> completely. In the case of Java Strings, we currently auto-coerce both
> ways, making any Java String-returning APIs very expensive since they
> must be coerced from a char[]-based String to a byte[]-based Ruby
> String. With the auto-coercion change, they would remain a Java String
> until you choose to coerce or an API you call calls to_str.
I think this change is influential to older codes. If users specify
Ruby types when giving variables from Java to Ruby, will it covers the
change? For example, by new method, "javaToRuby(Ruby runtime, Object
value, Class rubyType)" whereas we have "javaToRuby(Ruby runtime,
Object value)" only right now.
> Example:
>
> // Java
> public class Overloads {
> public void go(int i) { }
> public void go(long i) { }
> }
>
> # Ruby
> Overloads.new.go(123) # calls 'long' version, since it's the most
> natural conversion for Fixnum)
>
> Overloads.new.java_send(:go, [Java::int], 123) # calls "int" version
> explicitly
>
> method = Overloads.new.java_method(:go, [Java::int])
> method.call(123) # calls "int" version explicitly, with less overhead
> than java_send
This is nice feature. Then, how about interface implementation by
Ruby? Like in the below?
// Java
public interface Overloads {
public void go(int i);
public void go(long i);
}
// Ruby
class Overloads
include Java::Overloads
def go(i, [Java::int])
# implementation for int
end
def go(i, [Java::long])
#i implementation for long
end
end
Overloads.new
If this is possible, it would be useful when we implement interfaces
defined in some specification.
-Yoko
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email