2012-09-15 9 views
6

Przepraszam, jeśli zduplikowano (nie znalazłem)Czy "==" w Ruby zawsze ceni sobie równość?

To tylko w celu potwierdzenia, że ​​operator Ruby == zawsze wykonuje porównanie równości. tj.

a == b 

porównuje się jego wartość na wartość B, zamiast niż, jak Java, czy wskazują one na tym samym obiekcie w pamięci (do tej ostatniej rzeczy, w Ruby, należy użyć a.object_id == b.object_id).

Tak więc, w konsekwencji jest to bezpieczne, aby porównać wartości ciągów z == w Ruby (chociaż nie jest to bezpieczne w Javie)

Dzięki

Edycja:

Pytanie dotyczy domyślnego zachowania == dla dowolnego obiektu Ruby, ponieważ może wprowadzać w błąd programistów Java-C-C++ zakładając, że == b porównuje same referencje, a nie zawartość referencyjną.

W każdym razie, można sprawdzić ten kod, za pomocą strun

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 

Edycja 2.

Więc w Ruby, porównania

a == b 

kontrole A i wartości B

ale przypisanie

a = b 

nie kopiuje wartości, ale sprawia, że ​​i punktu B do ten sam obiekt!

kontynuacją poprzedniego kodu

puts one.object_id 
puts two.object_id 

puts " and now " 

one = two 

puts one.object_id 
puts two.object_id 
+1

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

+1

Odnośny link nie jest duplikatem to pytanie ... –

+0

Tak, pierwszą rzeczą, jaką sobie uświadomiłem, jest to, że w Ruby operator '==' i funkcja 'equals' są odwrócone do tego, czego oczekuje się w językach podobnych do języka C. – EliuX

Odpowiedz

3

W Ruby, == może być przeciążony, więc może to zrobić cokolwiek projektantowi klasy jesteś porównując chce to zrobić. Pod tym względem jest bardzo podobny do metody Javy equals().

Konwencja jest dla == do porównywania wartości, a większość klas stosuje się do tej konwencji, String. Więc masz rację, przy użyciu == do porównywania łańcuchów zrobi oczekiwaną rzecz.

Konwencja jest equal? zrobić porównanie odniesienia, więc testy a.object_id == b.object_id można także zapisać a.equal?(b). (Metoda equal? można zdefiniować zrobić coś niestandardowego, ale potem znowu, więc może object_id!)

(uwaga Side. Gdy znajdziesz się porównywania ciągów w Ruby, często powinien być za pomocą symboli zamiast)

+0

Downvoter: proszę wyjaśnić! Jeśli coś jest nie tak z moją odpowiedzią, chciałbym być oświetlony :) – Thomas

1

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

Kod:

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

Wyjście:

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 - Dodatkowe wyjście:

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

To jest mylące, ponieważ 'MyObject' nie definiuje żadnej z tych metod poprawnie. – Thomas

+0

Tak, to robi ... patrz edytuj ... –

+1

Przez "poprawnie" rozumiem "zgodnie z konwencją", która jest: "równa?" Oznacza równość odniesienia, "eql?" Ma wartość równości, a '==' nie równość wartości z typami konwersji. Artykuł, który powyższy został wyrwany z (http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/) wyjaśnia to dobrze, ale właśnie ten kod nie ma kontekstu, który faktycznie odpowiada na pytanie . – Thomas

0

Według t o "Język programowania Ruby" (Flanagan & Matsumoto) sekcja 4.6.7 strona 106

== jest operator równości. Określa, czy dwie wartości są równe, zgodnie z definicją "równości" lewy i operand.

A 3.8.3 Strona 74:

Każdy obiekt ma identyfikator przedmiotu, Fixnum, że można uzyskać metodą object_id. Wartość zwrócona przez tę metodę jest stała i niepowtarzalna przez cały okres istnienia obiektu.

To działa odwrotnie niż Java (co jest dla mnie zaskoczeniem).