[squeak-dev] The Inbox: Kernel-jar.1399.mcz
Jaromir Matas
m at jaromir.net
Tue May 4 18:06:07 UTC 2021
Hi Jakob,
Jakob Reschke wrote
> Oh well, I am not even sure whether sending both resume and then
> return to the Exception is even well-defined behavior according to the
> standard.
I'd say yes - e.g. in case of #outer.
Jakob Reschke wrote
> Since return is specified referring to the "active exception handler",
> it should return from the on: do: handler 1 in your example. So I
> would in fact expect to get '12' in both cases. Handler 2 is no longer
> active after the resume.
Great point! So now we have another question: what does it mean to re-signal
an exception that has already been signaled? (This is NOT the same as
#resignalAs)
ANSI doesn't seem to be against this kind of re-signaling an existing
exception. Here's what it says about #resume:
"
Message: resume
If the current exception action was activated as the result of sending the
message #outer to the
receiver, return a resumption value as the value of the #outer message.
If the receiver is a resumable exception a resumption value is returned as
the value of the message
that signaled the receiver.
"
So you're right we should expect '12' as a result rather than just '2'. Your
interpretation seems to be consistent with the specification of #outer. I
checked other implementations but each of them provides different answers :D
(except Pharo). I used this modified test example:
| x |
x:=''.
[
[1/0. x:=x,'B'] on: ZeroDivide do: [:ex | ex signal. x:=x,'A'. ex return].
"handler 1"
x:=x,'1'
] on: ZeroDivide do: [:ex | ex resume]. "handler 2"
x:=x,'2'.
x
Squeak/Pharo: answer inconsistently 'A2' or 'A12' depending on whether the
return is explicit or implicit.
VW: answers 'A12' - as a proper #outer (funny - their #outer answers 'A2'
which is wrong)
VA: answers 'A2' - totally flawed
Cuis raises an exception; re-signaling is simply prohibited :)
One more argument and then I'll leave it :) If you try the following example
where #return is replaced by #resume, Squeak (and Pharo and VA) will fail
completely raising a cannot return error:
| x |
x:=''.
[
[1/0. x:=x,'B'] on: ZeroDivide do: [:ex | ex signal. x:=x,'A'. ex resume].
"handler 1"
x:=x,'1'
] on: ZeroDivide do: [:ex | ex resume]. "handler 2"
x:=x,'2'.
x
VW however answers 'AB12' which is also consistent with the #outer
specification. I'd say it should be safe to implement this semantics, i.e.
#outer semantics for re-signaling, even if it's not explicitly mentioned in
ANSI.
I've even found a real use of re-signaling an exception in the trunk - see
DiskProxy>>comeFullyUpOnReload:
So my final suggestion is to define the behavior for re-signaling as
equivalent to #outer, to become consistent and avoid apparently incorrect
answers in above mentioned examples (I'm aware this is 99.9% academic
indeed):
Exception>>signal
"Ask ContextHandlers in the sender chain to handle this signal. The
default is to execute and return my defaultAction."
-----> signalContext ifNotNil: [^self outer]. "re-signalling an already
signalled exception is equivalent to sending #outer"
signalContext := thisContext contextTag.
^(thisContext nextHandlerContextForSignal: self) handleSignal: self
best,
-----
^[^ Jaromir
--
Sent from: http://forum.world.st/Squeak-Dev-f45488.html
More information about the Squeak-dev
mailing list
|