0

In the code below retry and ensure block is not working when there is an error.

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


puts( doCalc )

Please let me know what is the problem here.

asdfkjasdfjk
  • 3,784
  • 18
  • 64
  • 104

1 Answers1

3

Sorry about the previous suggestion. I've just noticed the actual cause of error. The following works as you'd assume it to:

def doCalc
  begin
    print( "Enter a number: " )
    aNum = gets().chomp()
    result = 100 / aNum.to_i
  #rescue Exception => e    # - dont catch Exception unless you REALLY need it.
  rescue => e               # - this catches StandardError and is usually enough
    result = 0
    puts( "Error: #{e}\nPlease try again." )   # <-- changed here
    retry   # retry on exception
  else
    msg = "Result = #{result}"
  ensure
    msg = "You entered '#{aNum}'. " + msg
  end
  return msg
end

You've actually had THREE errors thrown one after another.

First error ocurred as you planned - during the parsing and division. And it was caught by the rescue Exception => e properly.

But you cannot "add" an "exception" to a "string". Trying to "asd" + e + "asd" caused another error to be thrown what crashed your 'rescue' block. However, the immediatelly following 'ensure' block must run, so while your rescue block was about to quit and rise another error, the ensure block fired.

And the ensure block failed to add msg to the string, since msg was nil at the moment. So, for the third time an exception was raised, and it successfully has hidden all the previous exceptions.

In short: Note how I now replaced the add-exception-to-a-string with string interpolation. You cannot add e directly. You have to either use interpolation, or call e.to_s manually.

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
  • But I was reading "Book of ruby" and everywhere it uses this type of code and most of them are not working. What is the problem here? I mean the book says it should be an exception and they also showed the answer – asdfkjasdfjk Dec 04 '13 at 12:39
  • I was still editing the post. Please read it now. The `rescue` and `ensure` are working properly. You have failed at string-concatenation. – quetzalcoatl Dec 04 '13 at 12:41