Let's start with some basics. Put this into a file userinput.rb
:
print "Please enter a number: "
input = gets
puts input
Then run with ruby userinput.rb
. You get a prompt and the program outputs whatever you type in.
You want your input to be an integer, so let's use Integer()
to convert the input:
print "Please enter a number: "
input = gets
puts Integer(input)
Type in an integer and you'll get an integer output. Type in anything else and you'll get something like this:
userinput.rb:3:in `Integer': invalid value for Integer(): "asdf\n" (ArgumentError)
from userinput.rb:3:in `<main>'
Now you can build a loop that prompts the user until an integer is typed in:
input = nil # initialize the variable so you can invoke methods on it
until input.is_a?(Fixnum) do
print "Please enter a number: "
input = Integer(gets) rescue nil
end
The interesting part is input = Integer(gets) rescue nil
which converts the integer and, in case of an ArgumentError
like above, the error gets rescued and the input
var is nil again.
A more verbose way of writing this (except that this catches only ArgumentError
exceptions) would be:
input = nil # initialize the variable so you can invoke methods on it
until input.is_a?(Fixnum) do
print "Please enter a number: "
begin
input = Integer(gets)
rescue ArgumentError # calling Integer with a string argument raises this
input = nil # explicitly reset input so the loop is re-entered
end
end
Some notes:
- Please don't get confused by
Integer
andFixnum
.Integer
is the parent class that also encapsulates big numbers, but it's fairly standard to test forFixnum
(as in the loop head). You could also just use.is_a?(Integer)
without changing the behavior. - Most Ruby tutorials probably use
puts
overprint
, the latter's output doesn't end with a newline, which makes the prompt appear in one line.