Ruby: Condition as a variable does not work

Viewed 65

Just started learning looping and flow control in Ruby and got stuck with this exercise. I've been testing and searching for answers but did not find any so I'm posting here.

If I have my code setup like this:

ask_play = ''
loop do
    print "Play?: "
    ask_play = gets.chomp
    break if (ask_play == 'n') || (ask_play == 'N')
end

Then I exit out of the loop after entering n or N.

However, if I have my code setup like this:

ask_play = ''
play_stop = (ask_play == 'n') || (ask_play == 'N')
loop do
    print "Play?: "
    ask_play = gets.chomp
    break if play_stop
end

The condition does not seem to work. I still keep on looping even after typing in n or N and I'm just puzzled why.

2 Answers

play_stop = (ask_play == 'n') || (ask_play == 'N') gets evaluated before the loop begins. It sets the play_stop variable to false because the ask_play variable that you assigned to an empty string is neither n nor N. It looks like you want to encapsulate the logic of the condition. You can create a method and pass a value to it.

def play_stop(input)
  input == 'n' || input == 'N'
end

loop do
    print "Play?: "
    ask_play = gets.chomp
    break if play_stop(ask_play)
end

You could use a proc to encapsulate the condition:

ask_play = ''
play_stop = -> { ask_play == 'n' || ask_play == 'N' }

loop do
  print "Play?: "
  ask_play = gets.chomp
  break if play_stop.call
end

You could also pass the string to the proc instead of referring to the local variable:

play_stop = -> (s) { s == 'n' || s == 'N' }

loop do
  print "Play?: "
  break if play_stop.call(gets.chomp)
end

Procs also work nicely in case statements:

play_stop = -> (s) { s == 'n' || s == 'N' }

loop do
  print "Play?: "
  case gets.chomp
  when play_stop
    break
  end
end
Related