- Ruby 的运算符大多都是作为实例方法提供给我们使用的,因此我们可以很方便地定义或者重定义运算符,改变其原有的含义。但是,表 9.3 中列举的运算 符是不允许修改的。
二元运算符
class Point attr_reader :x, :y def initialize(x=0, y=0) @x, @y = x, y end def inspect # 用于显示 "(#{ x}, #{ y})" end #左侧是方法调用者定义时可以不写,右侧other就是方法的参数 def +(other) # x、y 分别进行加法运算 self.class.new(x + other.x, y + other.y) end def -(other) # x、y 分别进行减法运算 #如下改成Point.new(x - other.x, y - other.y)也行 self.class.new(x - other.x, y - other.y) endendpoint0 = Point.new(3, 6)point1 = Point.new(1, 8)p point0 #=> (3, 6)p point1 #=> (1, 8)#point0就是调用者(也叫方法接收者),+是方法,point1是方法的参数p point0 + point1 #=> (4, 14) p point0 - point1 #=> (2, -2)
(2)可定义的一元运算符有 +、-、~、! 4 个。它们分别以 +@、-@、~@、!@ 为方法名进行方法的定义。下面就让我们试试在 Point 类中定义这几个运算符:
class Point attr_reader :x, :y def initialize(x=0, y=0) @x, @y = x, y end def inspect # 用于显示 "(#{ x}, #{ y})" end def +@ dup # 返回自己的副本 end def -@ self.class.new(-x, -y) # 颠倒x、y 各自的正负 end def ~@ self.class.new(-y, x) # 使坐标翻转90 度 endendpoint = Point.new(3, 6)p +point #=> (3, 6)p -point #=> (-3, -6)p ~point #=> (-6, 3)
(3)数组、散列中的 obj[i] 以及 obj[i]=x 这样的方法,称为下标方法。定义下标方法时的方法名分别为 [] 和 []=。在代码清单 9.3 中,我们将会定义 Point 类实例 pt 的下标方法,实现以 v[0] 的形式访问 pt.x,以 v[1] 的形式访问 pt.y。
class Point attr_accessor :x, :y def initialize(x=0, y=0) @x, @y = x, y end def inspect # 用于显示 "(#{ x}, #{ y})" end def [](index) #这个定义看着别扭,实际调用时就是 接收者[index] case index when 0 x when 1 y else raise ArgumentError, "out of range `#{ index}'" end end def []=(index, val) #这个定义看着别扭,实际调用时就是 接收者[index]=val case index when 0 self.x = val when 1 self.y = val else
raise ArgumentError, "out of range `#{ index}'" end endendpoint = Point.new(3, 6)p point[0] #=> 3p point[1] = 2 #=> 2 必须把上面y访问级别改为attr_accessor,不然因为attr_reader只读,会报错没有y=这个写的方法p point[1] #=> 2p point[2] #=> 错误(ArgumentError)