对于一个简单的类结构类:
class Tiger
attr_accessor :name, :num_stripes
end
正确实现相等性的正确方法是什么,以确保==
,===
,eql?
等工作,并使类的实例在集合,哈希中很好地发挥作用等等。
修改
另外,当您想要根据未暴露在类外的状态进行比较时,实现相等性的好方法是什么?例如:
class Lady
attr_accessor :name
def initialize(age)
@age = age
end
end
在这里,我希望我的平等方法考虑到@age,但是Lady并没有将她的年龄暴露给客户。在这种情况下我是否必须使用instance_variable_get?
答案 0 :(得分:67)
要简化具有多个状态变量的对象的比较运算符,请创建一个方法,将所有对象的状态作为数组返回。然后只比较两种状态:
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
此外,如果您希望类的实例可用作哈希键,请添加:
alias_method :eql?, :==
def hash
state.hash
end
这些需要公开。
答案 1 :(得分:18)
一次测试所有实例变量的相等性:
def ==(other)
other.class == self.class && other.state == self.state
end
def state
self.instance_variables.map { |variable| self.instance_variable_get variable }
end
答案 2 :(得分:1)
通常使用==
运算符。
def == (other)
if other.class == self.class
@name == other.name && @num_stripes == other.num_stripes
else
false
end
end