<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style>
<!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.EmailStyle18
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang=EN-US link=blue vlink=purple>
<div class=Section1>
<p class=MsoNormal><span style='color:#1F497D'>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.<o:p></o:p></span></p>
<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='color:#1F497D'>Tomas<o:p></o:p></span></p>
<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>
<div>
<div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in'>
<p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span
style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> ironruby-core-bounces@rubyforge.org
[mailto:ironruby-core-bounces@rubyforge.org] <b>On Behalf Of </b>Peter Bacon
Darwin<br>
<b>Sent:</b> Friday, January 11, 2008 5:10 AM<br>
<b>To:</b> ironruby-core@rubyforge.org<br>
<b>Subject:</b> [Ironruby-core] Automatic conversion of bool to int<o:p></o:p></span></p>
</div>
</div>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><span lang=EN-GB>In irb we have:<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal style='margin-left:.5in'><span lang=EN-GB>1 + true<o:p></o:p></span></p>
<p class=MsoNormal style='margin-left:.5in'><span lang=EN-GB>=> TypeError:
true can’t be coerced into Fixnum<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-GB>In rbx we have:<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal style='margin-left:.5in'><span lang=EN-GB>1 + true<o:p></o:p></span></p>
<p class=MsoNormal style='margin-left:.5in'><span lang=EN-GB>=> 2<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-GB>There are the following methods for + in
Fixnum:<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-GB style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>public</span> <span style='color:blue'>static</span> <span
style='color:blue'>object</span> Add(<span style='color:blue'>int</span> self, <span
style='color:blue'>int</span> other)</span><span lang=EN-GB><o:p></o:p></span></p>
<p class=MsoNormal style='margin-left:.5in;text-autospace:none'><span
lang=EN-GB style='font-size:8.0pt;font-family:"Courier New";color:blue'>public</span><span
lang=EN-GB style='font-size:8.0pt;font-family:"Courier New"'> <span
style='color:blue'>static</span> <span style='color:blue'>double</span> Add(<span
style='color:blue'>int</span> self, <span style='color:blue'>double</span>
other)<o:p></o:p></span></p>
<p class=MsoNormal style='margin-left:.5in;text-autospace:none'><span
lang=EN-GB style='font-size:8.0pt;font-family:"Courier New";color:blue'>public</span><span
lang=EN-GB style='font-size:8.0pt;font-family:"Courier New"'> <span
style='color:blue'>static</span> <span style='color:blue'>object</span> Add(<span
style='color:#2B91AF'>CodeContext</span><span style='color:green'>/*!*/</span>
context, <span style='color:blue'>object</span> self, <span style='color:blue'>object</span>
other)<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-GB>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:<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.5pt;font-family:"Courier New"'>(FixnumOps.Add)(<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.5pt;font-family:"Courier New"'> (.bound
$arg0),<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.5pt;font-family:"Courier New"'>
(Converter.ConvertToInt32)(<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.5pt;font-family:"Courier New"'>
(Object)(.bound $arg1),<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.5pt;font-family:"Courier New"'> ),<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB style='font-size:8.5pt;font-family:"Courier New"'>)</span><span
lang=EN-GB><o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-GB>After some digging I found this method in
Ruby.Runtime.Converter:<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>private</span> <span style='color:blue'>static</span> <span
style='color:blue'>bool</span> HasImplicitNumericConversion(<span
style='color:#2B91AF'>Type</span> fromType, <span style='color:#2B91AF'>Type</span>
toType) {<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>if</span> (fromType.IsEnum) <span style='color:blue'>return</span>
<span style='color:blue'>false</span>;<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'><o:p> </o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>if</span> (fromType == <span style='color:blue'>typeof</span>(<span
style='color:#2B91AF'>BigInteger</span>)) {<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>if</span> (toType == <span style='color:blue'>typeof</span>(<span
style='color:blue'>double</span>)) <span style='color:blue'>return</span> <span
style='color:blue'>true</span>;<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>if</span> (toType == <span style='color:blue'>typeof</span>(<span
style='color:blue'>float</span>)) <span style='color:blue'>return</span> <span
style='color:blue'>true</span>;<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>if</span> (toType == <span style='color:blue'>typeof</span>(<span
style='color:#2B91AF'>Complex64</span>)) <span style='color:blue'>return</span>
<span style='color:blue'>true</span>;<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>return</span> <span style='color:blue'>false</span>;<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
}<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'><o:p> </o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>if</span> (fromType == <span style='color:blue'>typeof</span>(<span
style='color:blue'>bool</span>)) {<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>if</span> (toType == <span style='color:blue'>typeof</span>(<span
style='color:blue'>int</span>)) <span style='color:blue'>return</span> <span
style='color:blue'>true</span>;<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
<span style='color:blue'>return</span> HasImplicitNumericConversion(<span
style='color:blue'>typeof</span>(<span style='color:blue'>int</span>), toType);<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
}<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'><o:p> </o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'>
...<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span lang=EN-GB
style='font-size:8.0pt;font-family:"Courier New"'><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-GB>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.<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-GB>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?<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-GB>Regards,<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-GB>Pete<o:p></o:p></span></p>
</div>
</body>
</html>