+
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