Class constants
Prev
Contents
Contents
Exception processing: ensure
Next

 Ruby user's guideException processing: rescue 

An executing program can run into unexpected problems. A file that it it wants to read might not exist; the disk might be full when it wants to save some data; the user may provide it with some unsuitable kind of input.

ruby> file = open("some_file")
ERR: (eval):1:in `open': No such file or directory - some_file

A robust program will handle these situations sensibly and gracefully. Meeting that expectation can be an exasperating task. C programmers are expected to check the result of every system call that could possibly fail, and immediately decide what is to be done:

FILE *file = fopen("some_file", "r");
if (file == NULL) {
  fprintf( stderr, "File doesn't exist.\n" );
  exit(1);
}
bytes_read = fread( buf, 1, bytes_desired, file );
if (bytes_read != bytes_desired ) {
  /* do more error handling here ... */
}
...

This is such a tiresome practice that programmers can tend to grow careless and neglect it, and the result is a program that doesn't handle exceptions well. On the other hand, doing the job right can make programs hard to read, because there is so much error handling cluttering up the meaningful code.

In ruby, as in many modern languages, we can handle exceptions for blocks of code in a compartmentalized way, thus dealing with surprises effectively but not unduly burdening either the programmer or anyone else trying to read the code later. The block of code marked with begin executes until there is an exception, which causes control to be transferred to a block of error handling code, which is marked with rescue. If no exception occurs, the rescue code is not used. The following method returns the first line of a text file, or nil if there is an exception:

def first_line( filename )
  begin
    file = open("some_file")
    info = file.gets
    file.close
    info  # Last thing evaluated is the return value
  rescue
    nil   # Can't read the file? then don't return a string
  end
end

There will be times when we would like to be able to creatively work around a problem. Here, if the file we want is unavailable, we try to use standard input instead:

begin
  file = open("some_file")
rescue
  file = STDIN