Checking that multiple user inputs meet a certain condition before saving them as variables

35 Views Asked by At

Is there a way to combine these 2 blocks of code to make it less redundant?

puts "first number?"
num1 = gets.chomp.to_i
until num1.is_a?(Integer)
  puts "please enter an actual number"
  num1 = Integer(gets.chomp) rescue nil
end

puts "second number?"
num2 = gets.chomp.to_i
until num2.is_a?(Integer)
  puts "please enter an actual number"
  num2 = Integer(gets.chomp) rescue nil
end
1

There are 1 best solutions below

0
Cary Swoveland On

You could do that as follows.

def get_int(msg)
  puts msg
  loop do
    n = Integer(gets, exception: false)
    break n if n
    puts "please enter an actual number"
  end
end
num1 = get_int("first number?")
  #=> 16
num2 = get_int("second number?")
  #=> -4

The dialog in getting the value for num1 was as follows.

first number?
cat
please enter an actual number
72.1
please enter an actual number
16

The dialog in getting the value for num2 was as follows.

second number?
&dog
please enter an actual number
10/2
please enter an actual number
-4

See Kernel#Integer and Kernel#loop. Kernel#Integer was given the optional argument exception: false in Ruby v2.6.

One advantage of using loop is that it provides a degree of data encapsulation. Unlike while and until, loop takes a block, thereby keeping prying eyes away from the values of local variables defined within the block. I rarely use anything other than loop for looping.