rpg / xs2all.net writes:

> Hi,
> 
> As you probably all know.  This works:
> 
> 	irb> require 'complex'
> 	true
> 	irb> 3 + 2.im
> 	Complex(3, 2)
> 
> But my question is: why does this work?  What is going in ruby's head?
> As I understood from `Programming Ruby' 3 + 2.im is equivalent to
> 3.+(2.im).  I don't see fixnums having a method that adds complex
> numbers, so is 3 converted to a complex.  No, ruby would not know how
> to do that, would it?  So, maybe ruby changes this to (2.im).+3?

This is all the magic of Numeric#coerce.

When (say) Fixnum#+ is passed an argument it doesn't understand, it
tries to coerce itself and the argument to compatible types, and then
do the addition based on them. On this case, the argument isn't a
float or a fixnum, so Fixnum does the equivalent of

    res = (2.im).coerce(3)    #-> [Complex(3, 0), Complex(0, 2)]
    res[0] + res[1]           #-> Complex(3, 2)


In fact, you can have fun with coerce by emulating some of Perl's
auto-conversion of Strings to numbers:

    class String
      def coerce(n)
        if self['.']
          [n, Float(self)]
        else
          [n, Integer(self)]
        end
      end
    end

    1 + "23"        #-> 24
    23 * "1.23"     #=> 29.29


Regards


Dave