It is said that when we have a class Point and knows how to perform point * 3 like the following:

class Point
  def initialize(x,y)
    @x, @y = x, y
  end

  def *(c)
    Point.new(@x * c, @y * c)
  end
end

point = Point.new(1,2)
p point
p point * 3

Output:

#<Point:0x336094 @x=1, @y=2>
#<Point:0x335fa4 @x=3, @y=6>

but then,

3 * point

is not understood:

Point can't be coerced into Fixnum (TypeError)

So we need to further define an instance method coerce:

class Point
  def coerce(something)
    [self, something]
  end
end

p 3 * point

Output:

#<Point:0x3c45a88 @x=3, @y=6>

So it is said that 3 * point is the same as 3.*(point). That is, the instance method * takes an argument point and invoke on the object 3.

Now, since this method * doesn't know how to multiply a point, so

point.coerce(3)

will be called, and get back an array:

[point, 3]

and then * is once again applied to it, is that true?

Now, this is understood and we now have a new Point object, as performed by the instance method * of the Point class.

The question is:

  1. Who invokes point.coerce(3)? Is it Ruby automatically, or is it some code inside of * method of Fixnum by catching an exception? Or is it by case statement that when it doesn't know one of the known types, then call coerce?

  2. Does coerce always need to return an array of 2 elements? Can it be no array? Or can i

Edit
Report