George Constantin
George Constantin

Reputation: 13

ruby date validation on wrong input

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

Answers (2)

Holger Just
Holger Just

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

mabe02
mabe02

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:

  • prompt to enter a date (specifying the expected format)
  • gets and chomp the user input
  • validate the format
    • if valid, puts the date
    • if not valid, puts the error and start again

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

Related Questions