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

In Ruby operation

point - 20 # treating it as point - (20,20) 20 - point # treating it as (20,20) - point 

must 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 - qx, @y - qy) 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) pp - q pq - p pp * 3 p 5 * p pp - 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 the same as p - 30 

30 - p will actually be taken as p - 30 by the coerce function. Is it possible to make it work?

I am really surprised that the method - will not give an argument in 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 .

0
ruby class
May 10 '10 at 8:19
source share
1 answer

Subtraction is not a commutative operation, so you cannot just swap operands in coerce and expect it to work. coerce(something) should return [something_equivalent, self] . So, in your case, I think you should write your Point#coerce like this:

 def coerce(something) if something.is_a?(Fixnum) [Point.new(something, something), self] else [self, something] end end 

You need to slightly change the other methods, but I will leave it to you.

+1
May 10 '10 at 11:52 a.m.
source share
— -



All Articles