+ operator to perform vector addition of two
Point objects,
* operator to multiply a Point by a scalar,
– operator to do the equivalent of multiplying by
–1.
+ are simply methods with
punctuation for names.
Because there are unary and binary forms of
the – operator, Ruby uses the method name –@ for unary minus.
Here is a version of the Point class with mathematical operators defined:
[~/rubytesting/TheRubyProgrammingLanguage/Chapter7ClassesAndModules/point]$ cat -n point.rb
1 class Point
2 attr_reader :x, :y # Define accessor methods for our instance variables
3
4 include Comparable
5 include Enumerable
6
7 def initialize(x,y)
8 @x,@y = x, y
9 end
10
11 def to_s # Return a String that represents this point
12 "(#@x,#@y)" # Just interpolate the instance variables into a string
13 end
14
15 def chuchu
16 "Point: chuchu"
17 end
18 private :chuchu
19
20 def +(other) # Define + to do vector addition
21 Point.new(@x + other.x, @y + other.y)
22 end
23
24 def -@ # Define unary minus to negate both coordinates
25 Point.new(-@x, -@y)
26 end
27
28 def *(scalar) # Define * to perform scalar multiplication
29 return Point.new(@x*scalar, @y*scalar) if scalar.is_a? Numeric
30 return Point.new(@x*scalar.x, @y*scalar.y) if scalar.is_a? Point
31 end
32
33 def coerce(other)
34 [self, other]
35 end
36
37 def [](index)
38 case index
39 when 0, -2 then @x # Index 0 (or -2) is the X coordinate
40 when 1, -1 then @y # Index 1 (or -1) is the Y coordinate
41
42 when :x, "x" then @x # Hash keys as symbol or string for X
43 when :y, "y" then @y # Hash keys as symbol or string for Y
44 else nil # Arrays and hashes just return nil on bad indexes
45 end
46 end
47
48 def hash
49 code = 17
50 code = 37*code + @x.hash
51 code = 37*code + @y.hash
52 code
53 end
54
55 def eql?(o)
56 return @x.eql?(o.x) && @y.eql?(o.y) if o.instance_of? Point
57 false
58 end
59
60 def ==(o)
61 return @x == o.x && @y == o.y if o.instance_of? Point
62 false
63 end
64
65 def <=>(o)
66 return nil unless o.instance_of? Point
67 @x*@x+@y*@y <=> o.x*o.x+o.y*o.y
68 end
69
70 end
71
72 if __FILE__ == $0
73 p = Point.new(1,2)
74 q = Point.new(1,1)
75 puts p
76 puts -p
77 puts p+q
78 puts p*q
79 puts p*2
80 puts 2*p
81
82 puts "#{p[0]}, #{p[1]}"
83 puts "#{p[-2]}, #{p[-1]}"
84 puts "#{p[:x]}, #{p[:y]}"
85 puts "#{p['x']}, #{p['y']}"
86
87 m = { p => 1, q => 2 }
88 puts m[p]
89 puts m[q]
90
91
92 # It is not a total order relation
93 r = Point.new(2, 1)
94 puts p > r
95 puts r > p
96 puts r == p
97 puts q < p
98 puts "#{[p, q, r].sort}"
99 puts [p, q, r].min
100 puts [p, q, r, Point.new(4,3)].max
101
102
103 end
Casiano Rodriguez León 2015-01-07