Ruby拥有== AND eql的任何好理由? ? (与to_a和to_ary类似)
我知道eql? Hashes使用它来查看一个对象是否与一个键*
相匹配
def ==(rb)
如果你想支持==运算符,但必须有一个很好的理由,哈希不使用==。 这是为什么? 你什么时候有==和eql的定义? 那些不相等(例如,一个是另一个的别名)?
同样,为什么除了to_a之外还要to_ary?
出现这个问题是为了回应某人在另一个问题上给我的回答 。
*
当然,Hash也假定eql? == true表示哈希码相等。
而且,它基本上是一个非常的想法,以覆盖相等? ?
我不知道ruby中这种特殊选择的原因,但我只想指出平等是一个困难的概念。
Common Lisp,例如有eq,eql,equal,equalp,并且就此而言=
能够分辨对同一对象的两个引用,具有相同值的相同类型的两个不同对象,具有相同值但具有不同类型的两个对象等之间的差异是非常有用的。有多少变化是有意义的取决于语言中的含义。
如果我没记错(我不使用ruby),rubys谓词正在实现其中三种情况
==是价值平等
EQL? 是价值和类型的平等
等于? 仅适用于同一对象
==检查两个值是否相等,而eql? 检查它们是否相同且属于同一类型。
irb(main):001:0> someint = 17 => 17 irb(main):002:0> someint == 17 => true irb(main):003:0> someint.eql? 17 => true irb(main):004:0> someint.eql? 17.0 => false irb(main):005:0> someint == 17.0 => true irb(main):006:0>
正如你在上面看到的,eql? 还将测试两个值是否相同。 在与17.0比较的情况下,等于false,这是因为someint不是浮点值。
这提到to_a和to_ary(以及to_s和to_str,to_i和to_int)具有不同的严格程度。 例如,
17.to_s
说得通,
17.to_str
没有。
似乎Hash类没有to_ary方法(没有to_a),但是对于Array类,to_a和to_ary有不同的行为:
to_a:
归还自我。 如果在Array的子类上调用,则将接收器转换为Array对象。
to_ary:
归还自我。
上面的答案更多关于eql?
答案eql?
但这里有to_a
和to_ary
东西。 在Ruby的鸭子打字方案中,对象可以通过两种方式进行转换 – 松散且牢固。 松散的转换就像是说: foo
可以将自己表示为一个数组( to_a
)。 这就是to_a
, to_s
, to_i
和其他单字母的用途。 所以String可以将自己表示为一个数组,因此它实现了to_a
。 公司转换说了一些非常不同的东西: foo
是一个字符串( to_ary
)。 请注意,这不是foo
的类是String,而是foo和字符串是否可以互换 – 无论字符串是什么,foo都可以在逻辑上使用。 我的Ruby书中的例子是罗马数字类。 我们可以在任何可以使用正整数的地方使用罗马数字,因此Roman可以实现to_int
。 具有可互换关系的类需要实现公司转换,而松散则适用于几乎所有类。 确保在松散的情况下不要使用公司转换 – 解释器中内置的代码会严重误解你,你最终会遇到与C ++的reinterpet_cast<>
相当的错误。 不好。