Pergunta

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
Foi útil?

Solução

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.)

Outras dicas

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

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).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top