Всегда ли "==" в Ruby равнозначно равенству?

Извините, если дублируется (я не нашел его)

Это только для того, чтобы подтвердить, что оператор Руби == всегда выполняет сравнение на равенство Т.е.

a == b

сравнивает значение a со значением b, вместо того, чтобы, как в Java, указывать, указывают ли они на один и тот же объект в памяти (для этого, в Ruby, следует использовать a.object_id == b.object_id).

Таким образом, в результате безопасно сравнивать строковые значения с == в Ruby (хотя это небезопасно в Java)

Спасибо

Редактировать:

Вопрос заключается в поведении по умолчанию == для любого объекта Ruby, так как это может ввести в заблуждение программистов на Java-C-C++, предполагая, что == b сравнивает сами ссылки, а не содержимое ссылок.

В любом случае, вы можете проверить этот код, используя строки

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

Изменить 2.

Итак, в Ruby, сравнение

a == b

проверяет значения a и b

но, назначение

a = b

не копирует значения, но заставляет a и b указывать на один и тот же объект!

продолжая предыдущий код

puts one.object_id
puts two.object_id

puts " and now "

one = two

puts one.object_id
puts two.object_id

3 ответа

Решение

В рубине == может быть перегружен, поэтому он может делать все, что хочет разработчик класса, который вы сравниваете. В этом отношении это очень похоже на Java equals() метод.

Конвенция для == сделать сравнение значений, и большинство классов следуют этому соглашению, String включен. Итак, вы правы, используя == для сравнения строк сделаем ожидаемую вещь.

Конвенция для equal? сделать сравнение ссылок, так что ваш тест a.object_id == b.object_id также может быть написано a.equal?(b), (The equal? метод может быть определен, чтобы сделать что-то нестандартное, но опять же, так может object_id!)

(Примечание: когда вы сравниваете строки в Ruby, вам часто следовало бы вместо этого использовать символы.)

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

Код:

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

Выход:

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

Редактировать - Дополнительный вывод:

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

Согласно "Языку программирования Ruby" (Flanagan & Matsumoto), раздел 4.6.7, стр. 106.

== это оператор равенства. Он определяет, равны ли два значения, согласно определению левого операнда "равно".

И в 3.8.3 стр. 74:

Каждый объект имеет идентификатор объекта Fixnum, который вы можете получить с помощью метода object_id. Значение, возвращаемое этим методом, является постоянным и уникальным для времени жизни объекта.

Таким образом, это работает противоположно Java (удивительно для меня).

Другие вопросы по тегам