Basil
Basil

Reputation: 23

How can I check my input string?

Here is my code:

loop do
  print "Input word: "
  word = gets.chomp
  if word.nil? or word.empty?
    puts "Nothing to input."
  else
    if word.index(":") != -1
      puts "Illegal character ':'"
    else
      break
    end
  end
end

Is there a more elegant way to check the input string?

Upvotes: 2

Views: 5903

Answers (4)

Andrew Grimm
Andrew Grimm

Reputation: 81530

This separates the complex logic from the IO

def validation_message_for_word(word)
  case
  when (word.nil? or word.empty?) then "Nothing to input."
  when word.include?(":") then 'Illegal character ":".'
  else nil
  end
end

word = nil # To ensure word doesn't get thrown away after the loop
loop do
  print "Input word: "
  word = gets.chomp
  validation_message = validation_message_for_word(word)
  break if validation_message.nil?
  puts validation_message
end

Now, if you want to unit test it, you can give a variety of different strings to validation_message_for_word and test the return value.

If you needed internationalization, you could do

def validation_type_for_word(word)
  case
  when (word.nil? or word.empty?) then :no_input
  when word.include?(":") then :illegal_character
  else nil
  end
end

def validation_message(language, validation_type)
  {:en => {:no_input => "No input", :illegal_character => 'Illegal character ":"'},
   :lolcat => {:no_input => "Invizibl input", :illegal_character => 'Character ":" DO NOT LIEK'}}.fetch(language).fetch(validation_type)
end

word = nil # To ensure word doesn't get thrown away after the loop
loop do
  print "Input word: "
  word = gets.chomp
  validation_type = validation_type_for_word(word)
  break if validation_type.nil?
  puts validation_message(:lolcat, validation_type)
end

Upvotes: 2

Pavling
Pavling

Reputation: 3963

Depends what "elegant" means to you, but as a fan of refactoring conditional statements to easily readable extracted methods, I'd look at something like:

def has_valid_input(word)
  return true unless word.include?(":")
  puts "Illegal." 
  return false
end

def is_not_empty(word)
  return true unless word.empty?
  puts "empty"
  return false
end

loop do
  print "Input word: "
  word = gets.chomp
  break if is_not_empty(word) && has_valid_input(word)
end

Upvotes: 0

Mischa
Mischa

Reputation: 43298

Something like this?

loop do
  print "Input word: "
  word = gets.chomp

  if word.empty?
    puts "No input."
  elsif word.include?(":")
    puts "Illegal character ':'"
  else
    break
  end
end

Upvotes: 9

Tudor Constantin
Tudor Constantin

Reputation: 26861

I personally prefer avoiding nested if/else:

loop do
    print "Input word: "
    word = gets.chomp
    if word.nil? or word.empty?
        puts "Nothing to input."
        #break, exit, nothing, or whatever ....
    end
    if word.index(":") != 0
        puts "Illegal character ':'"
    else
        break
    end
end

Upvotes: 0

Related Questions