什么';这是在ruby中实现平等的正确方法
对于简单的类似结构的类:什么';这是在ruby中实现平等的正确方法,ruby,equality,Ruby,Equality,对于简单的类似结构的类: class Tiger attr_accessor :name, :num_stripes end 正确实现相等的正确方法是什么,以确保==、==、eql?等正常工作,从而使类的实例在集合、哈希等中很好地发挥作用 编辑 另外,当您希望基于未在类外公开的状态进行比较时,实现相等的好方法是什么?例如: class Lady attr_accessor :name def initialize(age) @age = age end end 在这
class Tiger
attr_accessor :name, :num_stripes
end
正确实现相等的正确方法是什么,以确保==
、==
、eql?
等正常工作,从而使类的实例在集合、哈希等中很好地发挥作用
编辑
另外,当您希望基于未在类外公开的状态进行比较时,实现相等的好方法是什么?例如:
class Lady
attr_accessor :name
def initialize(age)
@age = age
end
end
在这里,我希望我的平等方法考虑到@age,但这位女士不会向客户透露她的年龄。在这种情况下,我必须使用实例变量get吗?通常使用
=
操作符
def == (other)
if other.class == self.class
@name == other.name && @num_stripes == other.num_stripes
else
false
end
end
要简化具有多个状态变量的对象的比较运算符,请创建一个将对象的所有状态作为数组返回的方法。然后比较两种状态:
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
这些必须是公共的。要同时测试所有实例变量的相等性:
def ==(other)
other.class == self.class && other.state == self.state
end
def state
self.instance_variables.map { |variable| self.instance_variable_get variable }
end
谢谢然而,我认为如果您只定义==的话,那么类的实例在哈希和集合中的行为就不会像预期的那样。而且,我/think/that==不应该检查类型相等性(就像您的示例所做的那样)。这就是eql?应该这样做。这可能是错误的。只有你改变了,行为才会改变,皮特。上次我选中的
true==true
(和1+1==2
)仍然返回true
…我非常喜欢这种通过将比较委托给状态数组来比较对象的技巧。不幸的是,这已经结束了我的工作head@kraftydevil这确实是不幸的。对此我很抱歉。像这样的类比较怎么样:o.is\u a?(self.class)
?。我知道它的行为(后代),但我正在寻找最佳实践。@DonPaulie我不知道那里是否有最佳实践。我不太使用继承,所以我不必决定子类的实例是否应该等于其父类的实例。我会根据具体情况来考虑。这真的好得多,因为它可以确保你不会意外地漏掉任何变量。现在,自动使用每个实例变量可能会产生一些意想不到的后果,但我不确定,也不知道,直到有一天我感到惊讶。没错,您可以为这些特定情况添加可选参数,如“only”或“except”。