[Ironruby-core] Automatic conversion of bool to int

Peter Bacon Darwin bacondarwin at googlemail.com
Wed Jan 16 15:49:18 EST 2008


Since you are going to reimplement the conversions from scratch at some
point, can I offer the following patch to fix the particular bool to int
conversion problem for now?

It is also pretty trivial.

Regards,

Pete

 

From: ironruby-core-bounces at rubyforge.org
[mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Tomas Matousek
Sent: Friday,11 January 11, 2008 17:16
To: ironruby-core at rubyforge.org
Subject: Re: [Ironruby-core] Automatic conversion of bool to int

 

The conversions are wrong. In fact, they are quire arbitrary (the code is in
fact partly copied from IronPython). We have an item on our todo list to
reimplement them from scratch.

 

Tomas

 

From: ironruby-core-bounces at rubyforge.org
[mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Peter Bacon Darwin
Sent: Friday, January 11, 2008 5:10 AM
To: ironruby-core at rubyforge.org
Subject: [Ironruby-core] Automatic conversion of bool to int

 

In irb we have:

 

1 + true

=> TypeError: true can't be coerced into Fixnum

 

In rbx we have:

 

1 + true

=> 2

 

There are the following methods for + in Fixnum:

 

       public static object Add(int self, int other)

public static double Add(int self, double other)

public static object Add(CodeContext/*!*/ context, object self, object
other)

 

I expected that passing a bool into + operator would have ended up at the
third overload, which would give the correct behaviour when it tries to
coerce on the bool.  But it actually gets mapped to the first overload and
there is an implicit conversion of true to 1.  You can see this in the
resulting AST dump:

 

(FixnumOps.Add)(

    (.bound $arg0),

    (Converter.ConvertToInt32)(

        (Object)(.bound $arg1),

    ),

)

 

After some digging I found this method in Ruby.Runtime.Converter:

 

        private static bool HasImplicitNumericConversion(Type fromType, Type
toType) {

            if (fromType.IsEnum) return false;

 

            if (fromType == typeof(BigInteger)) {

                if (toType == typeof(double)) return true;

                if (toType == typeof(float)) return true;

                if (toType == typeof(Complex64)) return true;

                return false;

            }

 

            if (fromType == typeof(bool)) {

                if (toType == typeof(int)) return true;

                return HasImplicitNumericConversion(typeof(int), toType);

            }

 

            ...

 

Here you can see that bool is automatically converted to an int.  Is this
correct behaviour?  I appreciate that we can take any non-nil value as true
and nil as false but not the other way round.

 

ASIDE: In fact all three methods are added as "Applicable Targets" but the
int version gets there first.  Is there a heuristic for the order in which
overloads are considered?

 

Regards,

Pete

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20080116/7d8cc88c/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Converter.patch
Type: application/octet-stream
Size: 681 bytes
Desc: not available
Url : http://rubyforge.org/pipermail/ironruby-core/attachments/20080116/7d8cc88c/attachment.obj 


More information about the Ironruby-core mailing list