Возможно, вы можете рассмотреть этот общий подход для проверки пользовательского ввода, обратите внимание, что этот пример require 'date'
.
Итак, вы можете проверить, что пользовательский ввод является целым числом или числом с плавающей запятой илиформатированную дату или все, что вы можете добавить ...
Сначала определите массив вопросов, содержащий текст вопроса, метод проверки и способ преобразования входных данных, например:
questions = [
{text: "Enter an integer:", validate: :must_be_an_integer, convert: :my_to_i},
{text: "Enter a float:", validate: :must_be_a_float, convert: :my_to_f},
{text: "Enter a data as d-m-yyyy", validate: :must_be_a_formatted_date, convert: :to_formatted_date}
]
Затем определите некоторые методы, которые будут вызываться клавишей
:validate
, для проверки ввода пользователя:
def must_be_an_integer(num)
Integer(num).class == Integer rescue false
end
def must_be_a_float(num)
Float(num).class == Float && num.include?('.') rescue false
end
def must_be_a_formatted_date(date_str)
date = Date.strptime(date_str, "%d-%m-%Y") rescue false
return false unless date
date.year <= 9999 && date.year >= 1000
end
Определите также методы, требуемые клавишей
:convert
(необходимо передатьаргумент, поэтому
my_to_i
и
my_to_f
):
def my_to_i(num)
num.to_i
end
def my_to_f(num)
num.to_f
end
def to_formatted_date(date_str)
DateTime.strptime(date_str, "%d-%m-%y")
end
Наконец, итерации по вопросам:
res = questions.map do |question|
answer = nil
3.times do
puts question[:text]
u_input = gets.chomp
if send question[:validate], u_input
answer = send question[:convert], u_input
break
end
end
if answer.nil?
puts "C'mon man! Check your keyboard!" # after three input errors!!
break
end
{ question: question[:text], answer: answer }
end
Пример результата:
#=> [
{:question=>"Enter an integer:", :answer=>1},
{:question=>"Enter a float:", :answer=>1.1},
{:question=>"Enter a data as d-m-Y", :answer=>#<DateTime: 2020-10-27T00:00:00+00:00 ((2459150j,0s,0n),+0s,2299161j)>}
]