<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;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.EmailStyle20
        {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-GB link=blue vlink=purple>
<div class=Section1>
<p class=MsoNormal><span style='color:#1F497D'>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?<o:p></o:p></span></p>
<p class=MsoNormal><span style='color:#1F497D'>It is also pretty trivial.<o:p></o:p></span></p>
<p class=MsoNormal><span style='color:#1F497D'>Regards,<o:p></o:p></span></p>
<p class=MsoNormal><span style='color:#1F497D'>Pete<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 lang=EN-US style='font-size:10.0pt;font-family:
"Tahoma","sans-serif"'>From:</span></b><span lang=EN-US 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>Tomas Matousek<br>
<b>Sent:</b> Friday,11 January 11, 2008 17:16<br>
<b>To:</b> ironruby-core@rubyforge.org<br>
<b>Subject:</b> Re: [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-US 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 lang=EN-US style='color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span lang=EN-US style='color:#1F497D'>Tomas<o:p></o:p></span></p>
<p class=MsoNormal><span lang=EN-US 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 lang=EN-US style='font-size:10.0pt;font-family:
"Tahoma","sans-serif"'>From:</span></b><span lang=EN-US 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><span lang=EN-US><o:p> </o:p></span></p>
<p class=MsoNormal>In irb we have:<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal style='margin-left:.5in'>1 + true<o:p></o:p></p>
<p class=MsoNormal style='margin-left:.5in'>=> TypeError: true can’t be
coerced into Fixnum<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>In rbx we have:<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal style='margin-left:.5in'>1 + true<o:p></o:p></p>
<p class=MsoNormal style='margin-left:.5in'>=> 2<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>There are the following methods for + in Fixnum:<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><span 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><o:p></o:p></p>
<p class=MsoNormal style='margin-left:.5in;text-autospace:none'><span
style='font-size:8.0pt;font-family:"Courier New";color:blue'>public</span><span
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
style='font-size:8.0pt;font-family:"Courier New";color:blue'>public</span><span
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><o:p> </o:p></p>
<p class=MsoNormal>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></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal style='text-autospace:none'><span 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 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 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 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 style='font-size:8.5pt;
font-family:"Courier New"'> ),<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:8.5pt;font-family:"Courier New"'>)</span><o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>After some digging I found this method in Ruby.Runtime.Converter:<o:p></o:p></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal style='text-autospace:none'><span 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 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 style='font-size:8.0pt;
font-family:"Courier New"'><o:p> </o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span 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 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 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 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 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 style='font-size:8.0pt;
font-family:"Courier New"'>
}<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New"'><o:p> </o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span 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 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 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 style='font-size:8.0pt;
font-family:"Courier New"'>
}<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New"'><o:p> </o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New"'>
...<o:p></o:p></span></p>
<p class=MsoNormal style='text-autospace:none'><span style='font-size:8.0pt;
font-family:"Courier New"'><o:p> </o:p></span></p>
<p class=MsoNormal>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></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>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></p>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal>Regards,<o:p></o:p></p>
<p class=MsoNormal>Pete<o:p></o:p></p>
</div>
</body>
</html>