tags:

views:

407

answers:

4

I know eql? is used by Hashes to see if an object matches a key*, and you do

def ==(rb)

if you want to support the == operator, but there must be a good reason that Hashes don't use == instead. Why is that? When are you going to have definitions for == and eql? that are not equivalent (e.g. one is an alias to the other) ?

Similarly, why have to_ary in addition to to_a?

This question came up in response to an answer someone gave me on another question.

* Of course, a Hash also assumes eql? == true implies that the hashes codes are equal.

Also, is it basically a terribly idea to override equal? ?

+13  A: 

== checks if two values are equal, while eql? checks if they are equal AND of the same type.

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>

as you can see above, eql? will also test if both values are the same type. In the case of comparing to 17.0, which equates to false, it is because someint was not a floating point value.

John T
+7  A: 

I don't know the reasoning for this particular choice in ruby, but I'll just point out that equality is a difficult concept.

Common Lisp, for example has eq, eql, equal, equalp, and for that matter =

It can be very useful to be able to tell the difference between two references to the same object, two different objects of the same type with the same value, two objects with the same value but of different types, etc. How many variations make sense depends on what makes sense in the language.

If I recall it correctly (I don't use ruby), rubys predicates are implementing three of these cases

== is equality of value

eql? is equality of value and type

equal? is true only for the same object

simon
I can tell you actually thought about this answer. Among the ones that have been posted so far, this one most directly answers the question "why the distinction", which is what I was looking for. The others are more oriented toward "what's the difference". I also like how you point out this is a general language design question. Indeed, there is more than meets the eye when it comes to equality!
allyourcode
A: 

It seems that there is no to_ary method for the Hash class (no to_a), but for the Array class, to_a and to_ary have different behavior :

to_a :

Returns self. If called on a subclass of Array, converts the receiver to an Array object.

to_ary :

Returns self.

killy971
+2  A: 

This mentions that to_a and to_ary (and to_s and to_str , and to_i and to_int) have different levels of strictness. For example,

17.to_s

makes sense,

17.to_str

doesn't.

Andrew Grimm
Thanks for the link. That explains some of the reasoning, although I'm still not convinced.Also, I think you meant "makes sense _to Ruby_". To me, it makes very little sense that 17.to_s works but 17.to_str does not.
allyourcode
to_s/to_a/to_f/to_i are all explicit conversions. to_str/to_ary/to_int are all implicit conversions. For example, I have a URI library I wrote. My URI class implements to_str because if I have a method that takes a URI in String form as a parameter, I don't want to have to explicitly convert my URI object into a String before passing it as a parameter. The to_str method allows me to do this.
Bob Aman