TL; DR
Как правило, вы должны использовать ==
для сравнения чисел, когда вас не интересует числовой тип, который должен быть в большинстве случаев. Когда вы действительно заботитесь о типе, вы должны использовать сравнение на равенство объектов, унаследованное от Numeric # eql? .
Самое простое, что могло бы сработать
Вы можете просто спросить числовой объект, является ли он целым числом. Например, Числовое # целое число? позволяет попросить число проверить себя и вернуть логическое значение:
[1, 1.2, 1.02e+1].map(&:integer?)
#=> [true, false, false]
Если все, что вас волнует, это выяснить, является ли y целым числом, то это путь. Используя ваши собственные примеры:
y = 1
y.integer?
#=> true
y = 1.0
y.integer?
#=> false
Другие решения
Если вы пытаетесь сделать что-то более сложное, например, пытаетесь избежать автоматического преобразования числовых типов в сравнениях на равенство, единственным реальным ограничением является ваше воображение и идея, которую вы пытаетесь четко выразить в своем коде. В Numeric, Float, Integer, Object, String и других классах есть много методов, которые позволили бы вам вести разговоры типов и проводить строгие сравнения на равенство. Вот несколько примеров.
Использовать #eql?
Используйте различные методы для преобразования в целое число, а затем проверяйте со строгим равенством объектов:
y = 1.2
# All of these will return false.
y.eql? y.truncate
y.eql? y.floor
y.eql? y.to_i
y.eql? Integer(y)
Проверить остатки с помощью #zero?
Если вы хотите создать логическое выражение без автоматических числовых преобразований, сделанных с помощью ==
, вы можете использовать специфичный для класса метод, унаследованный от Numeric # zero? . Например:
(y % 1).zero?
y.modulo(1).zero?
Используйте #ceil или #floor с вычитанием
Если по определенным типам чисел по модулю не получается, вы можете использовать Float # ceil или Float # floor :
y = 1.2
(y - y.floor).zero?
#=> false
y = 1.02e+1
(y.floor - y).zero?
#=> false