Reputation: 13
Im a newbie to rails and I need your help on this one.
On the code below, if the first input is wrong and the second one is correct, the expression evaluates the first input. I would like that the user input is always evaluated.
require 'date'
puts "x is not a valid date"
until (x = gets.chomp) == ((x.match(/\d{4}-\d{1,2}-\d{1,2}$/).to_s &&Date.strptime(x, '%Y-%m-%d')rescue false) ==true)
Upvotes: 0
Views: 379
Reputation: 55758
In general, you should try to separate your data inout logic from data validation and later processing. That way, your methods concern themselves with only one thing each, which makes them much easier to reason about and thus more robust.
Here, we are introducing a valid_date_string?
method which checks if the passed input
object is a valid date string.
require 'date'
def valid_date_string?(input)
# First, we check that the given input is of the expected type.
# We do this here explicitly since we are validating a String. Most
# of the time, you would rely on duck typing instead.
return false unless input.is_a?(String)
# Then, we ensure roughly valid syntax (i.e. it looks like a date)
return false unless input =~ /\A\d+-\d+-\d+\z/
# Then, we "parse" it and split it into an array of year, month, day...
parts = input.split('-').map(&:to_i)
# ...and validate that this represents a valid date
Date.valid_date?(*parts)
end
In this solution, I took care not to rely on Exceptions for program flow since this is usually frowned upon as it can result in undetected bugs and has poor performance.
We can then use this method in some input loop to ask the user to input some value
def get_valid_date
loop do
input = gets.chomp
return input if valid_date_string?(input)
# Here, the user entered an invalid date. We can now do our
# error handling and try again.
puts "Invalid date given. Please try again..."
end
end
my_valid_date_string = get_valid_date
Upvotes: 1
Reputation: 2734
I would approach this problem as follows:
# date_test.rb
def date_input
puts "Please enter a date (format YYYY-MM-DD):"
d = gets.chomp
if d =~ /\d{4}-\d{1,2}-\d{1,2}$/
puts "You entered: #{d}"
else
puts "#{d} is not a valid date."
date_input
end
end
date_input
Explanation:
When you run it:
$ ruby date_test.rb
Please enter a date (format YYYY-MM-DD):
invalid date
invalid date is not a valid date.
Please enter a date (format YYYY-MM-DD):
2017-10-13
You entered: 2017-10-13
$
Upvotes: 0