Ruby拥有== AND eql的任何好理由? ? (与to_a和to_ary类似)

时间:2009-04-20 22:55:26

标签: ruby methods

我知道eql? Hashes使用它来查看对象是否与键*匹配,然后执行

def ==(rb)

如果你想支持==运算符,但必须有一个很好的理由,哈希不使用==。这是为什么?你什么时候有==和eql的定义?那些不是等价的(例如,一个是另一个的别名)?

同样,为什么除了to_a之外还要使用to_a?

这个问题是针对answer有人在another question给我的回复而提出的。

*当然,Hash也假定eql? == true表示哈希码相等。

另外,覆盖相等的基本上是一个非常可怕的想法吗? ?

5 个答案:

答案 0 :(得分:14)

==检查两个值是否相等,而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比较的情况下,等于假,这是因为someint不是浮点值。

答案 1 :(得分:10)

我不知道ruby中这种特殊选择的原因,但我只想指出平等是一个困难的概念。

Common Lisp,例如有eq,eql,equal,equalp,就此而言=

能够分辨出对同一对象的两个引用,具有相同值的相同类型的两个不同对象,具有相同值但具有不同类型的两个对象等之间的区别非常有用。变化是有意义的取决于语言中的含义。

如果我没记错(我不使用ruby),rubys谓词正在实现其中三种情况

==是值相等

EQL?是价值和类型的平等

等于?仅适用于同一对象

答案 2 :(得分:3)

This提到to_a和to_ary(以及to_s和to_str,to_i和to_int)具有不同的严格程度。例如,

17.to_s

有道理,

17.to_str

答案 3 :(得分:0)

似乎哈希类没有to_ary方法(没有to_a),但对于Array类,to_a和to_ary有不同的行为:

to_a:

  

返回自我。如果在Array的子​​类上调用,则将接收器转换为Array对象。

to_ary:

  

返回自我。

答案 4 :(得分:0)

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