Q:

Loop through multiple conditions until all of them are met

I'm using Ruby to get input from a user to provide new names for a list of files. I'm storing the names in an array, but before I store it, I have a series of conditions that I'm looping through to make sure that the user's input is valid. It essentially boils down to this (I've removed parts of the code that aren't relevant to the question):
puts "Rename file to:"
new_name = gets.chomp
new_name = check_input(new_name,@all_names)
@all_names << new_name   

def check_input(new_name,all_names)

    while new_name.match(/\s/)
        puts "Names must not contain spaces:"
        new_name = gets.chomp
    end

    while new_name.empty?
        puts "Please enter a name:"
        new_name = gets.chomp
    end

    while all_names.include? new_name
        puts "That name already exists. Please enter a different name:"
        new_name = gets.chomp
    end

    return new_name

end

Overall this works pretty well, but I want to make sure to loop through each "while" condition again and again, until all of the conditions are met. If, for instance, a name "abc" already exists, the user follows this order:

enters "abc" => "That name already exists. Please enter a different
name"
enters "a b c" => "Names must not contain spaces"
enters "abc" again => 

The last entry works successfully, but I don't want it to, since it's skipping over the condition that checks for duplicates. Is there a better way to loop through these conditions simultaneously, with each new entry?
Thank you for any help!

A:

Right idea with the loop, just the wrong place for it. You need to check each gets from the user against all possible invalid cases. What you were doing was checking until a single invalid case was passed and then going on to a different one, which didn't check if the previous case(s) still passed:
# outputs an error message and returns nil if the input is not valid.
# Otherwise returns the input
def check_input(input, all_names)
  if input.match(/\s/)
    puts "Name must not contain spaces:"
  elsif input.empty?
    puts "Please enter a name:"
  elsif all_names.include?(input)
    puts "That name already exists. Please enter a different name:"
  else
    input
  end
end

@all_names = ['abc']
puts "Rename file to:"
# keep gets-ing input from the user until the input is valid
name = check_input(gets.chomp, @all_names) until name
@all_names << name
puts @all_names.inspect

Since puts returns nil, check_input will return nil if the input is not valid. Otherwise, in the final else, we'll return the valid input and assign it to the variable name and stop executing the until loop.
Example run:

Rename file to:
  abc
  That name already exists. Please enter a different name:
  a b c
  Name must not contain spaces:
  abc
  That name already exists. Please enter a different name:
  abc23
  ["abc", "abc23"]

