Есть ли у Ruby веская причина иметь == И eql? ? (аналогично с to_a и to_ary) - PullRequest
3 голосов
/ 21 апреля 2009

я знаю eql? используется Хешами, чтобы увидеть, соответствует ли объект ключу *, и вы делаете

def ==(rb)

если вы хотите поддерживать оператор ==, но должна быть веская причина, по которой хэши не используют == вместо этого. Это почему? Когда вы будете иметь определения для == и eql? которые не эквивалентны (например, один является псевдонимом другого)?

Точно так же, почему to_ary в дополнение к to_a?

Этот вопрос возник в ответ на ответ кто-то дал мне на другой вопрос .

* Конечно, Hash также предполагает eql? == true означает, что хеш-коды равны.

Кроме того, это в принципе ужасная идея переопределить равные?

Ответы [ 5 ]

14 голосов
/ 21 апреля 2009

== проверяет, равны ли два значения, а eql? проверяет, равны ли они И того же типа.

irb(main):001:0> someint = 17
=> 17
irb(main):002:0> someint == 17
=> true
irb(main):003:0> someint.eql? 17
=> true
irb(main):004:0> someint.eql? 17.0
=> false
irb(main):005:0> someint == 17.0
=> true
irb(main):006:0>

как вы можете видеть выше, eql? также проверит, если оба значения имеют одинаковый тип. В случае сравнения с 17.0, что равно false, это потому, что someint не был значением с плавающей запятой.

10 голосов
/ 21 апреля 2009

Я не знаю причины такого конкретного выбора в ruby, но я просто укажу, что равенство - это сложная концепция.

Common Lisp, например, имеет eq, eql, equal, equalp, и в этом отношении =

Может быть очень полезно уметь различать две ссылки на один и тот же объект, два разных объекта одного типа с одинаковым значением, два объекта с одинаковым значением, но разных типов и т. Д. Сколько вариации имеют смысл, зависит от того, что имеет смысл в языке.

Если я правильно помню (я не использую ruby), предикаты rubys реализуют три из этих случаев

== равенство значений

EQL? равенство значения и типа

равны? верно только для одного и того же объекта

3 голосов
/ 21 апреля 2009

Здесь упоминается, что to_a и to_ary (и to_s и to_str, и to_i и to_int) имеют разные уровни строгости. Например,

17.to_s

имеет смысл,

17.to_str

нет.

0 голосов
/ 27 ноября 2011

Ответы выше больше, что ответ о eql?, но здесь что-то на to_a и to_ary. В схеме печатания утки Руби объекты могут быть преобразованы двумя способами - свободно и твердо. Свободное обращение - это как сказать: Может foo представлять как сам массив (to_a). Для этого и нужны to_a, to_s, to_i и другие однобуквенные. Таким образом, String может представлять себя как массив, поэтому он реализует to_a. Фирменное преобразование говорит что-то совсем другое: foo строка (to_ary). Обратите внимание, что это не тот случай, когда класс foo является String, но независимо от того, являются ли foo и строки взаимозаменяемыми - независимо от того, где ожидается строка, логически может использоваться foo. Пример в моей книге по Ruby относится к классу римских цифр. Мы можем использовать римскую цифру везде, где мы могли бы использовать положительное целое число, чтобы римляне могли реализовать to_int. Классы, которые имеют , являются взаимозаменяемыми отношениями , должны реализовывать твердое преобразование, в то время как свободный - почти для всех классов. Старайтесь не использовать твердое преобразование там, где свободен верный код - встроенный в интерпретатор код сильно вас неправильно поймет, и вы получите ошибки, сравнимые с reinterpet_cast<> в C ++. Не хорошо.

0 голосов
/ 21 апреля 2009

Кажется, что для класса Hash нет метода to_ary (нет to_a), но для класса Array поведение to_a и to_ary отличается:

to_a:

Возвращает себя. Если вызывается для подкласса Array, преобразует получателя в объект Array.

to_ary:

Возвращает себя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...