In Pharo (and other dialects) the ZeroDivide
exception is resumable. Why?. For instance, if you evaluate 1 / 0
and then proceed, the answer is the ZeroDivide
error. Why is this? Shouldn't ZeroDivide
be not resumable?
EDIT: Let's review this issue in more depth.
The problem here is that if the exception happens, what we get is the ZeroDivide
exception. So, the only reason I can think of for making this exception resumable is to enable the following:
[a / b] on: ZeroDivide do: [:ex | ex resume: self anythingButTheQuotient],
right?
But this could have also be written
[a / b] on: ZeroDevide do: [self anythingButTheQuotient]
without requiring the exception to be resumable.
Resumable exceptions make sense if there is an "interesting" #defaultAction
. But this seems not to be the case with ZeroDivide
.
One could be tempted to say that in many cases one has this kind of code:
b = 0 ifTrue: [^0] ifFalse: [^a / b]
so why not using 0 as the #defaultAction
? That would make the above code simpler (in those cases) and would only require a special handler in the (arguably) few ones that must behave differently. However, this would be a really bad decision because the default behavior would hide errors that, as we all know, the later they manifest the worst.
Yes, this is surprising at first sight, but the ANSI standard says:
Zero divide exceptions are resumable so any message in this protocol that signal such an exception may ultimately return to their sender.
The example you gave was trivial, but when installing the handler a few methods above, it's less trivial to resume the exception where it was signalled.
[self doSomethingComplex]
on: ZeroDivide
do:
[:exception |
"Handle zero divide as inf/nan as if performed in floating point arithmetic"
exception resume: exception dividend asFloat / 0.0]
In Squeak or Pharo, see the references to signalContext
instance variable in class Exception
. You'll see that resuming is your sole option for returning control to the signaller.