In programming, there are occasions (functions, methods) where it can be guaranteed that it will always succeed. On the other hand, there are occasions where a function or method is unable to complete and return a sensible result.
For example:
desired_result = 1.div(0)
Here the method can not return true/false for success because it already is designed to return the result of the calculation. But it also cannot return a number… That’s why it gives an exception. Exceptions are a second path for methods to return something: namely failure.
It is obvious how to access the primary return value (in the variable desired_result
), but how do you access this “second return value” of failure?
You “catch” or “rescue” the exception and let your code resolve the problem. Imagine you have a phone call and ask the receiver a math question. He either tells you the result, or didn’t understand the question (exception 1) or doesn’t know (exception 2). In order to handle exception type 1, you would probably repeat the question. For exception 2 you would either ask an easier question (if you are allowed to change questions) or you don’t handle the exception but just pass it on to your boss.
It is possible to distinguish what type of exception occured and then decide whether it is something you know how to handle. Exceptions can even have attributes attached (that’s why I like to call it some sort of return value): exception_object.message
and more. It is important that you catch only the specific exception type that you know to handle.
For details see here: Programming Ruby: The Pragmatic Programmer's Guide
and http://rubylearning.com/satishtalim/ruby_exceptions.html
Coming back to parse errors:
The parsed string either can be parsed to a numerical value, or it is maybe just garbage ("J$KN%&"
). If a number cannot be returned, an ArgumentError (“Cannot convert … to Length”) is thrown.
inputs = UI.inputbox(["Length"], ["?"], "Inputbox")
begin
length = inputs.first.to_l
rescue ArgumentError => exception_object
UI.messagebox("That was not a valid length. Too bad, the tool cannot continue.") # Or even: UI.messagebox(exception_object.message)
return
end
The obvious way to handle that would be to ask the user to input a (valid) length again. Therefore we need to bring up the same inputbox again.
length = nil
begin
inputs = UI.inputbox(["Length"], ["$garbage%&"], "Inputbox")
begin
length = inputs.first.to_l
rescue ArgumentError
UI.messagebox("That was not a valid length. Please repeat your input.") # You can drop this.
end
end until length.is_a?(Numeric)