Разрешить ввод только целых чисел в качестве аргумента в Ruby

Мне нужен сценарий Ruby, который принимает только целые числа в Ruby 2.1 и выше (т.е. обрабатывает Bignum, Fixnum и Integer).

У меня есть:

  def push(val)
    return "only integers can be used" if !val.is_a?(Fixnum) || !val.is_a?(Integer)

но если я добавлю Bignum, это не сработает. Как лучше всего это сделать? Или другая стратегия?

как насчет return "error" unless val.to_i > 0

Jake H 17.03.2018 03:15

@JakeHeidt Значит, вы говорите, что ни 0, ни -6 не являются целыми числами, а '11' - целыми?

mu is too short 17.03.2018 04:49

если он похож на утку и крякает, как утка ....

Jake H 17.03.2018 05:52
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
0
3
103
1

Ответы 1

Во-первых, ваша логика немного отстает. Ты хочешь сказать:

return an error if val is not a Fixnum and not an Integer

Это можно было бы выразить как:

if !val.is_a?(Fixnum) && !val.is_a?(Integer)

Если вы добавите Bignum к этому шаблону, он будет работать.

Во-вторых, Fixnum и Bignum устарели в пользу Integer, начиная с (AFAIK) Ruby 2.4. Достаточно удобно, что и Fixnum < Integer, и Bignum < Integer верны в Ruby с 2.1 по 2.3, поэтому нет смысла проверять is_a? Fixnum, is_a? Integer и is_a? Bignum, вы можете просто проверить is_a? Integer, поскольку:

  1. Начиная с Ruby 2.4, 10 и 10**100 являются как Integer, так и Fixnum и Bignum скоро исчезнут.
  2. В Ruby с 2.1 по 2.3 оба Fixnum (например, 11) и Bignum (например, 11*111) подклассы Integer, поэтому 11.is_a? Integer и (11*111).is_a? Integer верны.
  3. Fixnum и Bignum полностью ушли в 2.4, теперь есть только Integer.

Упростить до:

return "only integers can be used" if !val.is_a?(Integer)

или возможно:

return 'only integers can be used' unless val.is_a?(Integer)

или если вы хотите быть немного свободнее и разрешить '23', используйте Kernel#Integer:

def push(val)
  val = Integer(val)
  #...
rescue ArgumentError, TypeError
  return 'only integers can be used'
end

или, в зависимости от того, к какому количеству кода вы хотите применить rescue:

def push(val)
  begin
    val = Integer(val)
  rescue ArgumentError, TypeError
    return 'only integers can be used'
  end
  #...
end

или возможно:

def push(val)
  val = Integer(val) rescue nil
  return 'only integers can be used' if (val.nil?)
  #...
end

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