Main Content

Reading and checking user inputs - first lessons - Ruby

Archive - Originally posted on "The Horse's Mouth" - 2013-02-17 09:21:42 - Graham Ellis

Early programming exercises on a "learning to program in Xxxx" course involve asking the user to enter some pieces of data (usually numbers), doing a calculation using those numbers, and printing out a result. For that's a quite common requirement for a simple program - and this is the first realistic application that many delegates will have written.

When you read a number in from the user, you have the user enter a series of characters and that's actually got to be translated as a number. If the user enters letters rather than digits, you need to be able to deal with the situation, and you'll often need to look at the number and decide if it's within the valid range.

As part of the Learning to ptogram in Ruby course that ran last week, I wrote a new example of asking the user to enter a number, and then went through a series of examples each of which improved on the robustness of the program.

The first example - full source code [here] - does no checking what so ever:

  print "please enter a number from 3 to 7: "
  yousaid = gets.to_i
  puts "patronising congratulation #{yousaid}"


The second example - full source code [here] - checks. And we then have to consider what to do if the check fails ... so there's a loop in the code, an error message to be generated if a mistake is made. Here the replacement for the line that reads the data:

  yousaid = nil
  loop do
    yousaid = gets.to_i
    break if yousaid >=3 and yousaid <= 7
    print "error message! (please make this helpful) - try again "
  end


Programs will usually read multiple values, and if they're to do so, you won't want to repeat this block of lines multiple times in such a situation, so it's a good idea to put all those lines into a named block (called a function or a method) which you can repeatedly call up with just a single statement. The complete program showing how that work is [here]. The function code might look like this:

  def getnumber(min,max)
    yousaid = nil
    loop do
      yousaid = gets.to_i
      break if yousaid >=min and yousaid <= max
      print "error message! (please make this helpful) - try again "
    end
    return yousaid
  end


and the single line to call that:

  valgiven = getnumber(3,7)

In the program examples I've shown you so far, a user who enter a string of letters isn't properly catered for. There's nothing that says "has he really entered a number". In Ruby, to_i returns 0 if there's no number given, which will be a problem if zero were to be a valid entry. By changing to the Integer method for my final example (full source code [here]), I have trapped the error - doing so using an excpetion which is a built in trap that picks up the problem and runs my piece of rescue code. The loop becomes:

  loop do
    begin
      yousaid = Integer gets
    rescue
      yousaid = nil
    end
    break if yousaid != nil and yousaid >=min and yousaid <= max
    print "error message! (please make this helpful) - try again "
  end


As the course proceeds through Ruby Programming, I'll show delegates how to separate out common code such as our data entry function / method into a separate file, so that it can be shared not only between multiple requirements in the same program, but between multiple programs too. That's good, efficient coding .. and it also provides a consistent user interface for the user. A truely professional approach.