2012-09-15 23 views
6

Lo siento si está duplicado (no lo encontré)¿Es "==" en Ruby siempre valorar la igualdad?

Esto es solo para confirmar que el operador de Ruby == realiza siempre una comparación de igualdad. Es decir

a == b 

compara el valor de un valor de b en contra, en lugar de, como Java, ya sea que apuntan al mismo objeto en la memoria (Para esta última cosa, en Ruby, se debe utilizar a.object_id == b.object_id).

Por lo tanto, como consecuencia de que es seguro para comparar los valores de cadena con == en Ruby (aunque no es seguro hacerlo en Java)

Gracias

Editar:

La pregunta es sobre el comportamiento predeterminado == para cualquier objeto Ruby, ya que puede inducir a error a los programadores Java-C-C++ suponiendo que == b compara las referencias mismas, no los contenidos de referencia.

De todos modos, usted puede sacar de este código, el uso de cadenas

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 

Editar 2.

Así, en Ruby, la comparación

a == b 

controles A y los valores de b

pero, la asignación

a = b 

no copia los valores, sino que hace A y el B a el mismo objeto!

continuar con el código anterior

puts one.object_id 
puts two.object_id 

puts " and now " 

one = two 

puts one.object_id 
puts two.object_id 
+1

Sí. http://stackoverflow.com/questions/1710369/most-concise-way-to-test-string-equality-not-object-equality-for-ruby-strings – nneonneo

+1

El enlace se hace referencia no es un duplicado de esta pregunta ... –

+0

Sí, lo primero que me di cuenta es que en Ruby, el operador '==' y la función 'igual' están invertidos a lo que se espera en C idiomas similares. – EliuX

Respuesta

3

En Ruby, == puede sobrecargarse, por lo que podría hacer cualquier cosa el diseñador de la clase que está comparando quiere que haga. En ese sentido, es muy similar al método equals() de Java.

La convención es para == para hacer una comparación de valores, y la mayoría de las clases siguen esa convención, String incluida. Así que tienes razón, usando == para comparar cadenas hará lo esperado.

La convención es para equal? para hacer la comparación de referencia, por lo que su prueba de a.object_id == b.object_id también se podría escribir a.equal?(b). (El método equal? se podría definir a hacer algo no estándar, pero de nuevo, por lo que puede object_id!)

(Nota al margen:. Cuando te encuentras comparar cadenas en Ruby, que a menudo debe haber sido el uso de símbolos en su lugar)

+0

Downvoter: ¡por favor explique! Si algo está mal con mi respuesta, me encantaría estar iluminado :) – Thomas

1

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

el código:

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}" 

La salida:

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 

Edición - salida adicional:

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 
+1

Esto es engañoso, porque 'MyObject' no define ninguno de estos métodos correctamente. – Thomas

+0

Sí lo hace ... ver edición ... –

+1

Por "correctamente" me refiero a "según la convención", que es: "igual?" Hace igualdad de referencia, 'eql?' Hace igualdad de valor, y '==' no igualdad de valor con conversiones de tipo. El artículo del que se extrajo lo anterior (http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/) lo explica bien, pero este código carece del contexto que realmente responde a la pregunta . – Thomas

0

Según t O "El lenguaje de programación de Ruby" (Flanagan & Matsumoto), sección 4.6.7 página 106

== es el operador de igualdad. Determina si dos valores son iguales, de acuerdo con la definición de "igual" del operando de la izquierda.

Y en la página 74 3.8.3:

Cada objeto tiene un identificador de objeto, un Fixnum, que se puede obtener con el método object_id. El valor devuelto por este método es constante y único para la duración del objeto.

Por lo tanto, esto funciona al revés que Java (sorpresa para mí).

Cuestiones relacionadas