From: Ben Giddings Date: 2009-08-21T13:35:08+09:00 Subject: Re: extending ruby - handling errors On Aug 20, 2009, at 14:49, Gary Wright wrote: > I would argue that this is also the wrong approach because it > confuses responsibilities. To use programming by contract > terminology, > the requirement that the actual arguments to calculate_bounding_box > be numeric (or more specifically that they respond to ceil) is a > pre-condition and pre-conditions should be guaranteed by the caller, > not the callee. If you're writing calculate_bounding_box() as a bit of library code that will be used by other programmers, it is nice to provide helpful error messages. Someone using the method calculate_bounding_box() has no way of knowing that you're calling "ceil" internally, so getting an error back saying "NoMethodError: undefined method `ceil' for "2343":String" will be confusing. If you are nice enough to catch that error and throw a more useful error: "ArgumentError: width and height must be numeric" it will make debugging much easier. This doesn't mean it's not the responsibility of the caller to make sure it provides proper arguments, it just means that in the event the caller doesn't, you get clearer error messages. > Also, the example as written doesn't really solve the problem since > the caller will have to deal with ArgumentError instead of > NoMethodError. That depends on what you mean by "solve the problem". If the problem is "my program isn't working", solving the problem will involve looking at the traceback and figuring out what went wrong. In which case "ArgumentError: width and height must be numeric" is more helpful than "NoMethodError: undefined method `ceil'..." > In either case it indicates that the *caller* is > shirking its duty to guarantee the pre-conditions. Adding code in > the caller to guarantee numeric arguments is probably clearer than > arranging to respond to NoMethodError or ArgumentError. There's no reason not to do both. Clearly, whatever calls calculate_bounding_box() should make sure the parameters it supplies are what the method expects, but there's no reason calculate_bounding_box() can't anticipate a common exception, catch it then raise a more accurate and more helpful exception of its own. Ben