在红宝石中实现平等的正确方法是什么 [英] What's the right way to implement equality in ruby
问题描述
对于简单的类结构类:
class Tiger
attr_accessor :name, :num_stripes
end
正确实现平等的正确方法是什么,以确保 ==
, ===
, eql?
等,这样的实例的班级在组合,散列等方面表现良好。
what is the correct way to implement equality correctly, to ensure that ==
, ===
, eql?
, etc work, and so that instances of the class play nicely in sets, hashes, etc.
编辑
另外,当您要根据未在类外部公开的状态进行比较时,实现平等的一种好方法是什么?例如:
Also, what's a nice way to implement equality when you want to compare based on state that's not exposed outside the class? For example:
class Lady
attr_accessor :name
def initialize(age)
@age = age
end
end
在这里就像我的平等方法考虑@age一样,但这位女士并没有向客户透露自己的年龄。在这种情况下,我是否必须使用instance_variable_get?
here I'd like my equality method to take @age into account, but the Lady doesn't expose her age to clients. Would I have to use instance_variable_get in this situation?
推荐答案
要简化具有多个状态变量的对象的比较运算符,请创建一个该方法以数组形式返回对象的所有状态。然后只需比较两个状态:
To simplify comparison operators for objects with more than one state variable, create a method that returns all of the object's state as an array. Then just compare the two states:
class Thing
def initialize(a, b, c)
@a = a
@b = b
@c = c
end
def ==(o)
o.class == self.class && o.state == state
end
protected
def state
[@a, @b, @c]
end
end
p Thing.new(1, 2, 3) == Thing.new(1, 2, 3) # => true
p Thing.new(1, 2, 3) == Thing.new(1, 2, 4) # => false
此外,如果您希望将类的实例用作哈希键,请添加:
Also, if you want instances of your class to be usable as a hash key, then add:
alias_method :eql?, :==
def hash
state.hash
end
这些需要公开。
这篇关于在红宝石中实现平等的正确方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!