Yun
Yun

Reputation: 1

Loop until answer is a string

I'm trying to loop this question until the user's input is a string value:

Question: What is your name?

  • I don't want the user to just press enter and leave the name blank.
  • I don't want the user's input to be numeric/numbers.

Please see my code below:

name1 = gets.chomp.to_s    
loop do
  print "Please enter your name "
  name1 = gets.chomp.to_s
  if name1.empty?
    puts "No input."
  else name1.to_i
    puts "Illegal character ':'"
  end
end

With this code, I can't proceed to the next question even if I input a string value. Please help.

Upvotes: 0

Views: 399

Answers (2)

Stefan
Stefan

Reputation: 114188

Your code has several issues:

  1. Your input and output is out of order. You gather input before prompting and that input (from your first line) is never used:

    name1 = gets.chomp.to_s           # <- Ruby is waiting for input
    loop do
      print "Please enter your name " # <- user is prompted to enter name
      name1 = gets.chomp.to_s         # <- previous input is overwritten
      # ...
    end
    

    The first line should probably be deleted.

  2. gets might return nil, but chomp always returns a string. Calling to_s afterwards is therefore superfluous.

  3. Your if-else construct is actually:

    if name1.empty?
      puts "No input."
    else
      name1.to_i
      puts "Illegal character ':'"
    end
    

    So whenever the input is not empty?, you convert it to an integer (discarding the result) and print an error message. You probably want an elsif instead (/.../ is a regexp and \d matches a digit):

    if name1.empty?
      puts 'No input.'
    elsif name1.match? /\d/
      puts 'Digits not allowed.'
    end
    

    You could also use a case expression:

    case name1
    when ''
      puts 'No input.'
    when /\d/
      puts 'Digits not allowed.'
    end
    
  4. You never break out of your loop. The code keeps looping even if no error was found. This can be fixed by adding a break statement in an else branch (to either if or case):

      # ...
    else
      break
    end
    

Upvotes: 2

Zonet
Zonet

Reputation: 302

gets.chomp will always return a string, and as such there is no need to call to_s on the method.

If you don't want the user to be able to input any integers, you could use the following for a clean solution:

name.count("0-9") > 0

If this returns true, then you know that the user's input contains at least one number.

Upvotes: -1

Related Questions