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_ato_ary东西。 在Ruby的鸭子打字方案中,对象可以通过两种方式进行转换 – 松散且牢固。 松散的转换就像是说: foo可以将自己表示为一个数组( to_a )。 这就是to_ato_sto_i和其他单字母的用途。 所以String可以将自己表示为一个数组,因此它实现了to_a 。 公司转换说了一些非常不同的东西: foo是一个字符串( to_ary )。 请注意,这不是foo的类是String,而是foo和字符串是否可以互换 – 无论字符串是什么,foo都可以在逻辑上使用。 我的Ruby书中的例子是罗马数字类。 我们可以在任何可以使用正整数的地方使用罗马数字,因此Roman可以实现to_int 。 具有可互换关系的类需要实现公司转换,而松散则适用于几乎所有类。 确保在松散的情况下不要使用公司转换 – 解释器中内置的代码会严重误解你,你最终会遇到与C ++的reinterpet_cast<>相当的错误。 不好。