在 Ruby 中覆盖 Spaceship 运算符时实际发生了什么?
What actually happens when Spaceship operator is overwritten in Ruby?
我是 Ruby 的新手。有人可以解释 <=> 方法在下面的程序中是如何工作的吗?下面的 'other' 参数是如何使用的?
class Age
attr_reader :value
def initialize(value)
@value = value
end
def <=> (other) # What is actually happening here...
self.value <=> other.value # ..and here?
end
end
a = Age.new(7)
b = Age.new(3)
c = Age.new(9)
d = [a, b, c]
puts d.sort
让我们从d.sort
开始。 d
是一个数组,所以你应该阅读 Array#sort
。文档说排序 "will be done using the <=>
operator"。这意味着在对数组进行排序时,它将重复计算 x <=> y
,其中 x
和 y
是 d
的不同元素,以确定哪些元素是 bigger/smaller。
Ruby中的运算符有点棘手,因为它们实际上是变相的方法调用。 x <=> y
只是x.<=>(y)
的另一种写法。也就是说,x
有一个名为 <=>
的方法,它作为参数传递给 y
。因为d
的元素是Age
class的实例,所以Age
需要定义实例方法<=>
。所以当你看到 def <=> (other)
时,这与普通的方法定义(def foo(other)
)并没有什么不同,只是方法名称不同而已。
既然我们正在为 Age
个实例定义 <=>
,该方法实际上应该做什么?那么每个 Age
对象存储一个 @value
,所以直觉上 Age#<=>
应该比较 @value
。这就是 self.value <=> other.value
所做的。这是可行的,因为 value
returns 和 Fixnum
,幸运的是 Fixnum#<=>
内置于 Ruby 中以进行正确的比较。
关于幕后发生的事情的示例,我们可以尝试对包含我们不知道如何比较的值的数组进行排序:
[Age.new(3), 4].sort
# NoMethodError: undefined method `value' for 4:Fixnum
[4, Age.new(3)].sort
# ArgumentError: comparison of Fixnum with Age failed
这显示了对不同类型进行排序如何导致调用不同的 <=>
方法。
我是 Ruby 的新手。有人可以解释 <=> 方法在下面的程序中是如何工作的吗?下面的 'other' 参数是如何使用的?
class Age
attr_reader :value
def initialize(value)
@value = value
end
def <=> (other) # What is actually happening here...
self.value <=> other.value # ..and here?
end
end
a = Age.new(7)
b = Age.new(3)
c = Age.new(9)
d = [a, b, c]
puts d.sort
让我们从d.sort
开始。 d
是一个数组,所以你应该阅读 Array#sort
。文档说排序 "will be done using the <=>
operator"。这意味着在对数组进行排序时,它将重复计算 x <=> y
,其中 x
和 y
是 d
的不同元素,以确定哪些元素是 bigger/smaller。
Ruby中的运算符有点棘手,因为它们实际上是变相的方法调用。 x <=> y
只是x.<=>(y)
的另一种写法。也就是说,x
有一个名为 <=>
的方法,它作为参数传递给 y
。因为d
的元素是Age
class的实例,所以Age
需要定义实例方法<=>
。所以当你看到 def <=> (other)
时,这与普通的方法定义(def foo(other)
)并没有什么不同,只是方法名称不同而已。
既然我们正在为 Age
个实例定义 <=>
,该方法实际上应该做什么?那么每个 Age
对象存储一个 @value
,所以直觉上 Age#<=>
应该比较 @value
。这就是 self.value <=> other.value
所做的。这是可行的,因为 value
returns 和 Fixnum
,幸运的是 Fixnum#<=>
内置于 Ruby 中以进行正确的比较。
关于幕后发生的事情的示例,我们可以尝试对包含我们不知道如何比较的值的数组进行排序:
[Age.new(3), 4].sort
# NoMethodError: undefined method `value' for 4:Fixnum
[4, Age.new(3)].sort
# ArgumentError: comparison of Fixnum with Age failed
这显示了对不同类型进行排序如何导致调用不同的 <=>
方法。