2012-09-15 11 views
6

Scusate se duplicato (non ho trovato esso)"==" in Ruby vale sempre l'uguaglianza?

Questo è solo per confermare che Ruby dell'operatore == esegue sempre un confronto di uguaglianza. I.e.

a == b 

confronto di un valore rispetto al valore di b, invece che, come Java, sia che puntano allo stesso oggetto in memoria (per quest'ultima cosa, in Ruby, è necessario utilizzare a.object_id == b.object_id).

Così, di conseguenza è sicuro di confrontare i valori di stringa con == in Ruby (anche se non è sicuro di farlo in Java)

Grazie

Edit:

La domanda è sul comportamento == predefinito per qualsiasi oggetto Ruby, in quanto può ingannare i programmatori Java-C-C++ assumendo un == b confronta i riferimenti stessi, non i contenuti di riferimento.

Ad ogni modo, è possibile controllare questo codice, utilizzando stringhe

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 

Modifica 2.

Così, in Ruby, il confronto

a == b 

controlli A e valori di b

ma, l'assegnazione

a = b 

non copia i valori, ma fa un e punto b per lo stesso oggetto!

continuando con il codice precedente

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

Il link fa riferimento non è un duplicato di questa domanda ... –

+0

Sì, la prima cosa che ho capito è che in Ruby l'operatore '==' e la funzione 'equals' sono invertiti a ciò che è previsto in C come le lingue. – EliuX

risposta

3

In Ruby, == può essere sovraccarico, quindi si poteva fare nulla il progettista della classe si sta confrontando lo vuole fare. A tale proposito, è molto simile al metodo Java equals().

La convenzione è per == per eseguire il confronto dei valori e la maggior parte delle classi segue tale convenzione, String inclusa. Quindi hai ragione, utilizzando == per confrontare le stringhe farà la cosa prevista.

La convenzione è per equal? per fare il confronto di riferimento, in modo che il test di a.object_id == b.object_id potrebbe anche essere scritta a.equal?(b). (Il metodo equal? potrebbe essere definita di fare qualcosa di non standard, ma poi di nuovo, in modo da può object_id!)

(Nota a margine:. Quando ci si trova a confronto le stringhe in Ruby, spesso avrebbe dovuto essere l'uso di simboli invece)

+0

Downvoter: perfavore spiega! Se qualcosa non va nella mia risposta, mi piacerebbe essere illuminato :) – Thomas

1

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

Il codice:

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

L'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 - uscita aggiuntive:

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

Questo è fuorviante, perché 'MyObject' non definisce correttamente nessuno di questi metodi. – Thomas

+0

Sì, sì ... vedi modifica ... –

+1

Con "correttamente" intendo "secondo la convenzione", che è: "uguale?" Fa riferimento all'uguaglianza, "eql?" Vale l'uguaglianza e "==" equità di valore con conversioni di tipo. L'articolo di cui sopra è stato strappato (http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/) lo spiega bene, ma proprio a questo codice manca il contesto che effettivamente risponde alla domanda . – Thomas

0

Secondo t o "Il linguaggio di programmazione vermiglio" (Flanagan & Matsumoto), sezione 4.6.7 pagina 106

== è l'operatore di uguaglianza. Determina se due valori sono uguali, in base alla definizione di "uguale" dell'operando di sinistra.

E in 3.8.3 a pagina 74:

Ogni oggetto ha un identificatore di oggetto, un Fixnum, che è possibile ottenere con il metodo object_id. Il valore restituito da questo metodo è costante e unico per la durata dell'oggetto.

Quindi, questo funziona al contrario di Java (sorpresa per me).