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”.

My apologies for the brevity and lack of explanation (I’m about to try

to catch a train), but this might do the sort of thing that you want?

(I think for coerce to work as you’d expect you need the operands(?)

in the coerce array to be in the same order as in the calculation.

Sorry if that doesn’t make any sense! A fuller explanation will follow

quite a bit later if you need one.)

class Point

attr_accessor :x, :y

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

def -(q)

return Point.new(@x - q.x, @y - q.y) if q.kind_of? Point

Point.new(@x - q, @y - q)

end

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

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

def coerce(something); [Point::Coerce.new(something), self]; end

end

class Point::Coerce

attr_reader :value

def initialize(v); @value = v; end

def *§

puts “Point::Coerce #{@value} * #{p.inspect}”

Point.new(@value * p.x, @value * p.y)

end

def -§

puts “Point::Coerce #{@value} - #{p.inspect}”

Point.new(@value - p.x, @value - p.y)

end

end

p = Point.new(200,100)

q = Point.new(80,70)

puts

p p, q

puts

p (-p)

puts

p p - q

p q - p

puts

p p * 3

p 5 * p

puts

p p - 30

p 30 - p

On Mon, May 10, 2010 at 6:39 AM, Colin B.

[email protected] wrote:

end

puts

p (-p)

puts

p p - q

p q - p

puts

p p * 3

p 5 * p

puts

p p - 30

p 30 - p

While this explains the usage of the coerce method well, I’m not sure

that the answer to the original poster’s question is mu*

I may be wrong here, it’s early and I haven’t yet had a full cup of

coffee, but while multiplication of a point (vector) and a scalar

makes sense, I’m not sure that there is a conventional meaning to

subtraction (or addition) of a scalar and a vector.

Colin’s solution treats a scalar in this case as a unit point

multiplied by the scalar. If this is what’s wanted it can be done

without the separate Point::Coerce class

def coerce(something)

[Point.new(something, something), self]

end

–

Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/

Github: rubyredrick (Rick DeNatale) · GitHub

Twitter: @RickDeNatale

WWR: http://www.workingwithrails.com/person/9021-rick-denatale

LinkedIn: http://www.linkedin.com/in/rickdenatale