retry: Attempt to Execute Code Again After an Error

If you think an error condition may be transient or may be corrected (by the user, perhaps?), you can rerun all the code in a begin..end block using the keyword retry, as in this example that prompts the user to re-enter a value if an error such as ZeroDivisionError occurs:

retry.rb

def doCalc
    begin
        print( "Enter a number: " )
        aNum = gets().chomp()
        result = 100 / aNum.to_i
    rescue Exception => e
        result = 0
        puts( "Error: " + e.to_s + "
Please try again." )
        retry           # retry on exception
    else
        msg = "Result = #{result}"
    ensure
        msg = "You entered '#{aNum}'. " + msg
    end
    return msg
end

Note

When you want to append the message from an exception object such as e to a string such as "Error: ", Ruby 1.9 insists that you explicitly convert e to a string ( "Error: " + e.to_s), whereas Ruby 1.8 does the conversion for you ( "Error: " + e).

There is, of course, the danger that the error may not be as transient as you think, so if you use retry, you may want to provide a clearly defined exit condition to ensure that the code stops executing after a fixed number of attempts.

You could, for example, increment a local variable in the begin clause. (If you do this, make sure it is incremented before any code that is liable to generate an exception since once an exception occurs, the remainder of the code prior to the rescue clause will be skipped!) Then test the value of that variable in the rescue section, like this:

rescue Exception => e
    if aValue < someValue then
        retry
    end

Here is a complete example, in which I test the value of a variable named tries to ensure no more than three tries to run the code without error before the exception-handling block exits:

retry2.rb

def doCalc
    tries = 0
    begin
        print( "Enter a number: " )
        tries += 1
        aNum = gets().chomp()
        result = 100 / aNum.to_i
    rescue Exception => e
        msg = "Error: " + e.to_s
        puts( msg )
        puts( "tries = #{tries}" )
        result = 0
        if tries < 3 then # set a fixed number of retries
           retry
        end
    else
        msg = "Result = #{result}"
    ensure
        msg = "You entered '#{aNum}'. " + msg
    end
    return msg
end

If the user were to enter 0 three times in a row, this would be the output:

Enter a number: 0
Error: divided by 0
tries = 1
Enter a number: 0
Error: divided by 0
tries = 2
Enter a number: 0
Error: divided by 0
tries = 3
You entered '0'. Error: divided by 0
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.201.217