In Ruby, how to implement 20 - point and point - 20 using coerce() ?

Posted by Jian Lin on Stack Overflow See other posts from Stack Overflow or by Jian Lin
Published on 2010-05-10T08:19:08Z Indexed on 2010/05/10 8:24 UTC
Read the original article Hit count: 316

Filed under:
|
|
|

In Ruby, the operation of

point - 20
20 - point

are to be implemented.

But the following code:

class Point

  attr_accessor :x, :y

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

  def -(q)
    if (q.is_a? Fixnum)
      return Point.new(@x - q, @y - q)
    end
    Point.new(@x - q.x, @y - q.y)
  end

  def -@
    Point.new(-@x, -@y)
  end

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

  def coerce(something)
    [self, something]
  end

end

p = Point.new(100,100)
q = Point.new(80,80)

p (-p)

p p - q
p q - p

p p * 3
p 5 * p

p p - 30
p 30 - p

Output:

#<Point:0x2424e54 @x=-100, @y=-100>
#<Point:0x2424dc8 @x=20, @y=20>
#<Point:0x2424d3c @x=-20, @y=-20>
#<Point:0x2424cc4 @x=300, @y=300>
#<Point:0x2424c38 @x=500, @y=500>
#<Point:0x2424bc0 @x=70, @y=70>
#<Point:0x2424b20 @x=70, @y=70>

30 - p will actually be taken as p - 30 by the coerce function. Can it be made to work?

I am actually surprise that the - method won't coerce the argument this way:

class Fixnum
  def -(something)
    if (/* something is unknown class */)
      a, b = something.coerce(self)
      return -(a - b)   # because we are doing a - b but we wanted b - a, so it is negated
    end
  end
end

that is, the function returns a negated version of a - b instead of just returning a - b.

© Stack Overflow or respective owner

Related posts about ruby

Related posts about coerce