Is "==" in Ruby always value equality?
Asked Answered
L

3

6

Sorry if duplicated (I didn't find it)

This is only to confirm that Ruby's operator == performs always an equality comparison. I.e.

a == b

compares a's value against b's value, instead than, like Java, whether they point to the same object in memory (For this latter thing, in Ruby, you should use a.object_id == b.object_id).

Thus, as a consequence it is safe to compare string values with == in Ruby (while it is not safe to do so in Java)

Thanks

Edit:

The question is on the the default == behavior for any Ruby object, as it can mislead Java-C-C++ programmers assuming a==b compares references themselves, not the reference contents.

Anyway, you can check out this code, using strings

one="hello"
two="he"
two << "llo"

if one == two
  puts "surprise: comparing values, not like in Java"
end

if not one.object_id == two.object_id
  puts "obvious: do this to compare references"
end

Edit 2.

So, in Ruby, the comparison

a == b

checks a's and b's values

but, the assignment

a = b

does not copy values, but makes a and b point to the same object !

continuing with the previous code

puts one.object_id
puts two.object_id

puts " and now "

one = two

puts one.object_id
puts two.object_id
Lareine answered 15/9, 2012 at 8:28 Comment(3)
Yes. #1710869Delrio
The referenced link is not a duplicate of this question...Houk
Yes the first thing i realized is that in Ruby the operator == and the function equals are inverted to what it is expected in C like languages.Approachable
U
3

In Ruby, == can be overloaded, so it could do anything the designer of the class you're comparing wants it to do. In that respect, it's very similar to Java's equals() method.

The convention is for == to do value comparison, and most classes follow that convention, String included. So you're right, using == for comparing strings will do the expected thing.

The convention is for equal? to do reference comparison, so your test a.object_id == b.object_id could also be written a.equal?(b). (The equal? method could be defined to do something nonstandard, but then again, so can object_id!)

(Side note: when you find yourself comparing strings in Ruby, you often should have been using symbols instead.)

Unanswerable answered 15/9, 2012 at 8:34 Comment(0)
H
1

From http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/.

The code:

class MyObject
end
object1 = MyObject.new
object2 = object1
object3 = MyObject.new

puts "Object 1 is == to object 2: #{object1 == object2}"
puts "Object 1 is eql? to object 2: #{object1.eql? object2}"
puts "Object 1 is equal? to object 2: #{object1.equal? object2}"
puts "Object 1 is == to object 3: #{object1 == object3}"
puts "Object 1 is eql? to object 3: #{object1.eql? object3}"
puts "Object 1 is equal? to object 3: #{object1.equal? object3}"

The output:

Object 1 is == to object 2: true
Object 1 is eql? to object 2: true
Object 1 is equal? to object 2: true
Object 1 is == to object 3: false
Object 1 is eql? to object 3: false
Object 1 is equal? to object 3: false

Edit - Additional output:

irb(main):001:0> class MyObject
irb(main):002:1> end
=> nil
irb(main):003:0> object1 = MyObject.new
=> #<MyObject:0x281bc08>
irb(main):006:0> object1.respond_to?( '=='.to_sym )
=> true
irb(main):007:0> object1.respond_to?( 'eql?'.to_sym )
=> true
irb(main):013:0> MyObject.superclass
=> Object
Houk answered 15/9, 2012 at 8:35 Comment(7)
This is misleading, because MyObject doesn't define any of these methods properly.Unanswerable
By "properly" I mean "according to convention", which is: equal? does reference equality, eql? does value equality, and == does value equality with type conversions. The article that the above was ripped from (skorks.com/2009/09/ruby-equality-and-object-comparison) explains this well, but just this code lacks the context that actually answers the question.Unanswerable
I disagree... unless it is overridden, that is how every object will work - the code is self-explanatory, and stands alone.Houk
Also, I referenced the article, for those who felt otherwise.Houk
The point is that it is overridden in all standard classes (String, Fixnum, whatnot), which is what the original question was about. So the default implementation in Object is rarely used. Like I said: misleading.Unanswerable
I believe the original question was about all classes, with strings being used as one example. At any rate, all methods perform normally, until overridden - kinda goes without saying...Houk
I think your example does not clarify the point. See example on strings on my question.Lareine
L
0

According to "The Ruby programming language" (Flanagan & Matsumoto), section 4.6.7 page 106

== is the equality operator. It determines whether two values are equal, according to the lefthand operand's definition of "equal".

And in 3.8.3 page 74:

Every object has an object identifier, a Fixnum, that you can obtain with the object_id method. The value returned by this method is constant and unique for the lifetime of the object.

So, this works the opposite than Java (surprise to me).

Lareine answered 15/9, 2012 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.