Hi all,
You can signal an already signaled exception; the nested #signal will start searching for an exception handler from the most recently created exception handler.
I wonder if this is a legitimate and reasonable interpretation of ANSI's #signal: Quote: The current exception environment is searched for an exception handler whose exception selector matches the signaled exception. The search proceeds from the most recently created exception handler to the oldest exception handler.
Repeated #signal would differ from #outer in that #outer starts serching for a handler from the current handler context and not from the most recently created handler context.
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
Current implementation will ignore the ZeroDivide handler and open a debugger as the default action. It because currently a repeated signal is made equivalent to #outer.
If you agree with the above interpretation then The Inbox: Kernel-jar.1407 provides its implementation and Tests-jar.464 some tests.
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
Here's a simple example:
[1/o] on: Error do: [:ex | [[ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide]] on: MessageNotUnderstood do: [Transcript show: #MNU] ]
or even
[1/o] on: Error do: [:ex | self dissect: ex]
instead of
[[1/o] on: ZeroDivide do: [Transcript show: #ZeroDivide]] on: MessageNotUnderstood do: [Transcript show: #MNU]
Does this make sense?
Thanks for your opinion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Does this make sense?
Another option seems you could dispatch your handler (or double-dispatch) to the signaled Exception.
- Chris
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker@gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show:
#ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer]. + signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail@jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show:
#ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer].
- signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi Jaromir,
Thanks for working on this! I'm possibly a bit late on the party, but I noticed that current #signal only keeps the messageText, not any other custom properties of an exception. I'm not sure whether this is the expected behavior. :)
Think of this revised example:
[(KeyNotFound key: #plonk) signal] on: Error do: [:ex | [ex signal] on: KeyNotFound do: [:ex2 | Transcript show: ex2]]
It will print out "Key not found: nil" to the Transcript, instead of printing the original key.
Without diving deeper into this discussion, my first impression would have been that some kind of #freshCopy (maybe with a better name?) would be a more holistic approach to honor any state in subclasses of Exception. What do you think? :-)
Best, Christoph
--- Sent from Squeak Inbox Talk
On 2022-02-06T11:42:46+01:00, mail@jaromir.net wrote:
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail at jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show:
#ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer]. + signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi Christoph,
Thanks for the example! This was actually my original idea how re-signaling an existing exception should work :) It’s implemented in Kernel-jar.1407 (now in Treated) - check it out… it really returns `Key not found: plonk` as you would expect too. Unfortunately I can’t recall why I went with the less ambitious Kernel-jar.1446 (now in Trunk) eventually. If you find this more reasonable, why not try to revive it? Thank you, best, Jaromir
From: christoph.thiede@student.hpi.uni-potsdam.demailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Friday, June 10, 2022 13:30 To: squeak-dev@lists.squeakfoundation.orgmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
Thanks for working on this! I'm possibly a bit late on the party, but I noticed that current #signal only keeps the messageText, not any other custom properties of an exception. I'm not sure whether this is the expected behavior. :)
Think of this revised example:
[(KeyNotFound key: #plonk) signal] on: Error do: [:ex | [ex signal] on: KeyNotFound do: [:ex2 | Transcript show: ex2]]
It will print out "Key not found: nil" to the Transcript, instead of printing the original key.
Without diving deeper into this discussion, my first impression would have been that some kind of #freshCopy (maybe with a better name?) would be a more holistic approach to honor any state in subclasses of Exception. What do you think? :-)
Best, Christoph
--- Sent from Squeak Inbox Talkhttps://github.com/hpi-swa-lab/squeak-inbox-talk
On 2022-02-06T11:42:46+01:00, mail@jaromir.net wrote:
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail at jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer].
- signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi Christoph, I think I remember… My original interpretation of ANSI about sending #signal to an existing exception resulted in Kernel-jar.1407. However, later I noticed this wording in #messageText section: “Subsequent sends of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message will also return this value.” … this “generated by” lead me to a more limited/conservative interpretation that is currently in the Trunk.
I believe Kernel-jar.1407 could be considered an extension of ANSI specification - your example indicates it’d be probably more logical or practical than the current one. I haven’t seen re-sending signal to existing exceptions implemented in other systems though.
How about to try after the release? :) Thanks for bringing this up! Best, jaromir
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 17:18 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
Thanks for the example! This was actually my original idea how re-signaling an existing exception should work :) It’s implemented in Kernel-jar.1407 (now in Treated) - check it out… it really returns `Key not found: plonk` as you would expect too. Unfortunately I can’t recall why I went with the less ambitious Kernel-jar.1446 (now in Trunk) eventually. If you find this more reasonable, why not try to revive it? Thank you, best, Jaromir
From: christoph.thiede@student.hpi.uni-potsdam.demailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Friday, June 10, 2022 13:30 To: squeak-dev@lists.squeakfoundation.orgmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
Thanks for working on this! I'm possibly a bit late on the party, but I noticed that current #signal only keeps the messageText, not any other custom properties of an exception. I'm not sure whether this is the expected behavior. :)
Think of this revised example:
[(KeyNotFound key: #plonk) signal] on: Error do: [:ex | [ex signal] on: KeyNotFound do: [:ex2 | Transcript show: ex2]]
It will print out "Key not found: nil" to the Transcript, instead of printing the original key.
Without diving deeper into this discussion, my first impression would have been that some kind of #freshCopy (maybe with a better name?) would be a more holistic approach to honor any state in subclasses of Exception. What do you think? :-)
Best, Christoph
--- Sent from Squeak Inbox Talkhttps://github.com/hpi-swa-lab/squeak-inbox-talk
On 2022-02-06T11:42:46+01:00, mail@jaromir.net wrote:
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail at jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer].
- signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi Christoph, Yes, the “fresh copy” of an exception is probably the best and simplest solution and you and Chris were right! I forgot about the subclasses and their instance variables :)
So what would you think about this simple fix:
#signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self copy refresh signal]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
… where:
#refresh signalContext := handlerContext := outerContext := nil
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 23:56 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph, I think I remember… My original interpretation of ANSI about sending #signal to an existing exception resulted in Kernel-jar.1407. However, later I noticed this wording in #messageText section: “Subsequent sends of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message will also return this value.” … this “generated by” lead me to a more limited/conservative interpretation that is currently in the Trunk.
I believe Kernel-jar.1407 could be considered an extension of ANSI specification - your example indicates it’d be probably more logical or practical than the current one. I haven’t seen re-sending signal to existing exceptions implemented in other systems though.
How about to try after the release? :) Thanks for bringing this up! Best, jaromir
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 17:18 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
Thanks for the example! This was actually my original idea how re-signaling an existing exception should work :) It’s implemented in Kernel-jar.1407 (now in Treated) - check it out… it really returns `Key not found: plonk` as you would expect too. Unfortunately I can’t recall why I went with the less ambitious Kernel-jar.1446 (now in Trunk) eventually. If you find this more reasonable, why not try to revive it? Thank you, best, Jaromir
From: christoph.thiede@student.hpi.uni-potsdam.demailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Friday, June 10, 2022 13:30 To: squeak-dev@lists.squeakfoundation.orgmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
Thanks for working on this! I'm possibly a bit late on the party, but I noticed that current #signal only keeps the messageText, not any other custom properties of an exception. I'm not sure whether this is the expected behavior. :)
Think of this revised example:
[(KeyNotFound key: #plonk) signal] on: Error do: [:ex | [ex signal] on: KeyNotFound do: [:ex2 | Transcript show: ex2]]
It will print out "Key not found: nil" to the Transcript, instead of printing the original key.
Without diving deeper into this discussion, my first impression would have been that some kind of #freshCopy (maybe with a better name?) would be a more holistic approach to honor any state in subclasses of Exception. What do you think? :-)
Best, Christoph
--- Sent from Squeak Inbox Talkhttps://github.com/hpi-swa-lab/squeak-inbox-talk
On 2022-02-06T11:42:46+01:00, mail@jaromir.net wrote:
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail at jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer].
- signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi Christoph, Let me know if it works; if not whether the “copy refresh” fix below works. I’ve never seen re-signaling an exception in real code, thanks for the link. At least it makes sense trying to fix it :) (different systems struggle too; little survey: https://forum.world.st/The-Inbox-Kernel-jar-1399-mcz-tp5129370p5129434.html) Thanks, Jaromir
From: Christoph Thiedemailto:christoph.thiede@student.hpi.uni-potsdam.de Sent: Saturday, June 11, 2022 1:20 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Fyio - here is a practical example of resignaling an exception (but I won't guarantee that it's idiomatic): https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/LinqLo...
I suppose that it's broken now, but I haven't checked yet.
Am 11.06.2022 00:21 schrieb Jaromir Matas mail@jaromir.net:
Hi Christoph,
Yes, the “fresh copy” of an exception is probably the best and simplest solution and you and Chris were right! I forgot about the subclasses and their instance variables :)
So what would you think about this simple fix:
#signal
"Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction.
Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self copy refresh signal].
signalContext := thisContext contextTag.
^(thisContext nextHandlerContextForSignal: self) handleSignal: self
… where:
#refresh
signalContext := handlerContext := outerContext := nil
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 23:56 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
I think I remember… My original interpretation of ANSI about sending #signal to an existing exception resulted in Kernel-jar.1407. However, later I noticed this wording in #messageText section:
“Subsequent sends of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message will also return this value.”
… this “generated by” lead me to a more limited/conservative interpretation that is currently in the Trunk.
I believe Kernel-jar.1407 could be considered an extension of ANSI specification - your example indicates it’d be probably more logical or practical than the current one. I haven’t seen re-sending signal to existing exceptions implemented in other systems though.
How about to try after the release? :)
Thanks for bringing this up!
Best,
jaromir
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 17:18 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
Thanks for the example! This was actually my original idea how re-signaling an existing exception should work :) It’s implemented in Kernel-jar.1407 (now in Treated) - check it out… it really returns
`Key not found: plonk`
as you would expect too.
Unfortunately I can’t recall why I went with the less ambitious Kernel-jar.1446 (now in Trunk) eventually.
If you find this more reasonable, why not try to revive it?
Thank you,
best,
Jaromir
From: christoph.thiede@student.hpi.uni-potsdam.demailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Friday, June 10, 2022 13:30 To: squeak-dev@lists.squeakfoundation.orgmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
Thanks for working on this! I'm possibly a bit late on the party, but I noticed that current #signal only keeps the messageText, not any other custom properties of an exception. I'm not sure whether this is the expected behavior. :)
Think of this revised example:
[(KeyNotFound key: #plonk) signal] on: Error do: [:ex | [ex signal] on: KeyNotFound do: [:ex2 | Transcript show: ex2]]
It will print out "Key not found: nil" to the Transcript, instead of printing the original key.
Without diving deeper into this discussion, my first impression would have been that some kind of #freshCopy (maybe with a better name?) would be a more holistic approach to honor any state in subclasses of Exception. What do you think? :-)
Best, Christoph
--- Sent from Squeak Inbox Talkhttps://github.com/hpi-swa-lab/squeak-inbox-talk
On 2022-02-06T11:42:46+01:00, mail@jaromir.net wrote:
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail at jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer].
- signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi Jaromir,
yes, my TBInterrupt was broken indeed, and yes, your proposed patch fixed it indeed. :-) I have put Kernel-ct.1481 & Tests-ct.490 into the inbox. Do you think we can merge it in this form? :)
Best,
Christoph
________________________________ Von: Squeak-dev squeak-dev-bounces@lists.squeakfoundation.org im Auftrag von Jaromir Matas mail@jaromir.net Gesendet: Samstag, 11. Juni 2022 09:50:21 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph, Let me know if it works; if not whether the “copy refresh” fix below works. I’ve never seen re-signaling an exception in real code, thanks for the link. At least it makes sense trying to fix it :) (different systems struggle too; little survey: https://forum.world.st/The-Inbox-Kernel-jar-1399-mcz-tp5129370p5129434.html) Thanks, Jaromir
From: Christoph Thiedemailto:christoph.thiede@student.hpi.uni-potsdam.de Sent: Saturday, June 11, 2022 1:20 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Fyio - here is a practical example of resignaling an exception (but I won't guarantee that it's idiomatic): https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/LinqLo...
I suppose that it's broken now, but I haven't checked yet.
Am 11.06.2022 00:21 schrieb Jaromir Matas mail@jaromir.net:
Hi Christoph,
Yes, the “fresh copy” of an exception is probably the best and simplest solution and you and Chris were right! I forgot about the subclasses and their instance variables :)
So what would you think about this simple fix:
#signal
"Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction.
Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self copy refresh signal].
signalContext := thisContext contextTag.
^(thisContext nextHandlerContextForSignal: self) handleSignal: self
… where:
#refresh
signalContext := handlerContext := outerContext := nil
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 23:56 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
I think I remember… My original interpretation of ANSI about sending #signal to an existing exception resulted in Kernel-jar.1407. However, later I noticed this wording in #messageText section:
“Subsequent sends of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message will also return this value.”
… this “generated by” lead me to a more limited/conservative interpretation that is currently in the Trunk.
I believe Kernel-jar.1407 could be considered an extension of ANSI specification - your example indicates it’d be probably more logical or practical than the current one. I haven’t seen re-sending signal to existing exceptions implemented in other systems though.
How about to try after the release? :)
Thanks for bringing this up!
Best,
jaromir
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 17:18 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
Thanks for the example! This was actually my original idea how re-signaling an existing exception should work :) It’s implemented in Kernel-jar.1407 (now in Treated) - check it out… it really returns
`Key not found: plonk`
as you would expect too.
Unfortunately I can’t recall why I went with the less ambitious Kernel-jar.1446 (now in Trunk) eventually.
If you find this more reasonable, why not try to revive it?
Thank you,
best,
Jaromir
From: christoph.thiede@student.hpi.uni-potsdam.demailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Friday, June 10, 2022 13:30 To: squeak-dev@lists.squeakfoundation.orgmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
Thanks for working on this! I'm possibly a bit late on the party, but I noticed that current #signal only keeps the messageText, not any other custom properties of an exception. I'm not sure whether this is the expected behavior. :)
Think of this revised example:
[(KeyNotFound key: #plonk) signal] on: Error do: [:ex | [ex signal] on: KeyNotFound do: [:ex2 | Transcript show: ex2]]
It will print out "Key not found: nil" to the Transcript, instead of printing the original key.
Without diving deeper into this discussion, my first impression would have been that some kind of #freshCopy (maybe with a better name?) would be a more holistic approach to honor any state in subclasses of Exception. What do you think? :-)
Best, Christoph
--- Sent from Squeak Inbox Talkhttps://github.com/hpi-swa-lab/squeak-inbox-talk
On 2022-02-06T11:42:46+01:00, mail@jaromir.net wrote:
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail at jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer].
- signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Hi Christoph, +1 Hooray, I guess now the re-signaling is working as intended at last :) Thanks for noticing it wasn’t still right and showing the example. Best, Jaromir
--
From: Thiede, Christophmailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Sunday, June 12, 2022 17:29 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
yes, my TBInterrupt was broken indeed, and yes, your proposed patch fixed it indeed. :-) I have put Kernel-ct.1481 & Tests-ct.490 into the inbox. Do you think we can merge it in this form? :)
Best,
Christoph
Von: Squeak-dev squeak-dev-bounces@lists.squeakfoundation.org im Auftrag von Jaromir Matas mail@jaromir.net Gesendet: Samstag, 11. Juni 2022 09:50:21 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph, Let me know if it works; if not whether the “copy refresh” fix below works. I’ve never seen re-signaling an exception in real code, thanks for the link. At least it makes sense trying to fix it :) (different systems struggle too; little survey: https://forum.world.st/The-Inbox-Kernel-jar-1399-mcz-tp5129370p5129434.html) Thanks, Jaromir
From: Christoph Thiedemailto:christoph.thiede@student.hpi.uni-potsdam.de Sent: Saturday, June 11, 2022 1:20 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Fyio - here is a practical example of resignaling an exception (but I won't guarantee that it's idiomatic): https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/LinqLo...
I suppose that it's broken now, but I haven't checked yet.
Am 11.06.2022 00:21 schrieb Jaromir Matas mail@jaromir.net:
Hi Christoph,
Yes, the “fresh copy” of an exception is probably the best and simplest solution and you and Chris were right! I forgot about the subclasses and their instance variables :)
So what would you think about this simple fix:
#signal
"Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction.
Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self copy refresh signal].
signalContext := thisContext contextTag.
^(thisContext nextHandlerContextForSignal: self) handleSignal: self
… where:
#refresh
signalContext := handlerContext := outerContext := nil
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 23:56 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
I think I remember… My original interpretation of ANSI about sending #signal to an existing exception resulted in Kernel-jar.1407. However, later I noticed this wording in #messageText section:
“Subsequent sends of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message will also return this value.”
… this “generated by” lead me to a more limited/conservative interpretation that is currently in the Trunk.
I believe Kernel-jar.1407 could be considered an extension of ANSI specification - your example indicates it’d be probably more logical or practical than the current one. I haven’t seen re-sending signal to existing exceptions implemented in other systems though.
How about to try after the release? :)
Thanks for bringing this up!
Best,
jaromir
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 17:18 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
Thanks for the example! This was actually my original idea how re-signaling an existing exception should work :) It’s implemented in Kernel-jar.1407 (now in Treated) - check it out… it really returns
`Key not found: plonk`
as you would expect too.
Unfortunately I can’t recall why I went with the less ambitious Kernel-jar.1446 (now in Trunk) eventually.
If you find this more reasonable, why not try to revive it?
Thank you,
best,
Jaromir
From: christoph.thiede@student.hpi.uni-potsdam.demailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Friday, June 10, 2022 13:30 To: squeak-dev@lists.squeakfoundation.orgmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
Thanks for working on this! I'm possibly a bit late on the party, but I noticed that current #signal only keeps the messageText, not any other custom properties of an exception. I'm not sure whether this is the expected behavior. :)
Think of this revised example:
[(KeyNotFound key: #plonk) signal] on: Error do: [:ex | [ex signal] on: KeyNotFound do: [:ex2 | Transcript show: ex2]]
It will print out "Key not found: nil" to the Transcript, instead of printing the original key.
Without diving deeper into this discussion, my first impression would have been that some kind of #freshCopy (maybe with a better name?) would be a more holistic approach to honor any state in subclasses of Exception. What do you think? :-)
Best, Christoph
--- Sent from Squeak Inbox Talkhttps://github.com/hpi-swa-lab/squeak-inbox-talk
On 2022-02-06T11:42:46+01:00, mail@jaromir.net wrote:
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail at jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer].
- signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
Merged! And thank you for the fast feedback! :-)
Best,
Christoph
________________________________ Von: Squeak-dev squeak-dev-bounces@lists.squeakfoundation.org im Auftrag von Jaromir Matas mail@jaromir.net Gesendet: Sonntag, 12. Juni 2022 18:36:26 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph, +1 Hooray, I guess now the re-signaling is working as intended at last :) Thanks for noticing it wasn’t still right and showing the example. Best, Jaromir
--
From: Thiede, Christophmailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Sunday, June 12, 2022 17:29 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
yes, my TBInterrupt was broken indeed, and yes, your proposed patch fixed it indeed. :-) I have put Kernel-ct.1481 & Tests-ct.490 into the inbox. Do you think we can merge it in this form? :)
Best,
Christoph
Von: Squeak-dev squeak-dev-bounces@lists.squeakfoundation.org im Auftrag von Jaromir Matas mail@jaromir.net Gesendet: Samstag, 11. Juni 2022 09:50:21 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph, Let me know if it works; if not whether the “copy refresh” fix below works. I’ve never seen re-signaling an exception in real code, thanks for the link. At least it makes sense trying to fix it :) (different systems struggle too; little survey: https://forum.world.st/The-Inbox-Kernel-jar-1399-mcz-tp5129370p5129434.html) Thanks, Jaromir
From: Christoph Thiedemailto:christoph.thiede@student.hpi.uni-potsdam.de Sent: Saturday, June 11, 2022 1:20 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Fyio - here is a practical example of resignaling an exception (but I won't guarantee that it's idiomatic): https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/LinqLo...
I suppose that it's broken now, but I haven't checked yet.
Am 11.06.2022 00:21 schrieb Jaromir Matas mail@jaromir.net:
Hi Christoph,
Yes, the “fresh copy” of an exception is probably the best and simplest solution and you and Chris were right! I forgot about the subclasses and their instance variables :)
So what would you think about this simple fix:
#signal
"Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction.
Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self copy refresh signal].
signalContext := thisContext contextTag.
^(thisContext nextHandlerContextForSignal: self) handleSignal: self
… where:
#refresh
signalContext := handlerContext := outerContext := nil
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 23:56 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
I think I remember… My original interpretation of ANSI about sending #signal to an existing exception resulted in Kernel-jar.1407. However, later I noticed this wording in #messageText section:
“Subsequent sends of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message will also return this value.”
… this “generated by” lead me to a more limited/conservative interpretation that is currently in the Trunk.
I believe Kernel-jar.1407 could be considered an extension of ANSI specification - your example indicates it’d be probably more logical or practical than the current one. I haven’t seen re-sending signal to existing exceptions implemented in other systems though.
How about to try after the release? :)
Thanks for bringing this up!
Best,
jaromir
From: Jaromir Matasmailto:mail@jaromir.net Sent: Friday, June 10, 2022 17:18 To: The general-purpose Squeak developers listmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Christoph,
Thanks for the example! This was actually my original idea how re-signaling an existing exception should work :) It’s implemented in Kernel-jar.1407 (now in Treated) - check it out… it really returns
`Key not found: plonk`
as you would expect too.
Unfortunately I can’t recall why I went with the less ambitious Kernel-jar.1446 (now in Trunk) eventually.
If you find this more reasonable, why not try to revive it?
Thank you,
best,
Jaromir
From: christoph.thiede@student.hpi.uni-potsdam.demailto:Christoph.Thiede@student.hpi.uni-potsdam.de Sent: Friday, June 10, 2022 13:30 To: squeak-dev@lists.squeakfoundation.orgmailto:squeak-dev@lists.squeakfoundation.org Subject: Re: [squeak-dev] Re-signalling an already signaled exception
Hi Jaromir,
Thanks for working on this! I'm possibly a bit late on the party, but I noticed that current #signal only keeps the messageText, not any other custom properties of an exception. I'm not sure whether this is the expected behavior. :)
Think of this revised example:
[(KeyNotFound key: #plonk) signal] on: Error do: [:ex | [ex signal] on: KeyNotFound do: [:ex2 | Transcript show: ex2]]
It will print out "Key not found: nil" to the Transcript, instead of printing the original key.
Without diving deeper into this discussion, my first impression would have been that some kind of #freshCopy (maybe with a better name?) would be a more holistic approach to honor any state in subclasses of Exception. What do you think? :-)
Best, Christoph
--- Sent from Squeak Inbox Talkhttps://github.com/hpi-swa-lab/squeak-inbox-talk
On 2022-02-06T11:42:46+01:00, mail@jaromir.net wrote:
Hi, just an update: I've sent a proposal to the Inbox: Kernel-jar.1446 with the following code:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Sending #signal to an already signaled exception generates a new exception of the same type with the same messageText"
signalContext ifNotNil: [^self class signal: messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
If possible I'd like to withdraw my previous contribution to #signal making repeated #signal sends equivalent to sending #outer, to prevent future code from using that misleading approach. Subsequent #signal sends are NOT equivalent to #outer and they have their own subtly different meaning discussed here - provided my interpretation of ANSI is right this time :)
Thanks for your time and apologies for previous confusion.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
On 2022-02-05T18:48:39+01:00, mail at jaromir.net wrote:
Hi Chris,
On 2022-02-04T17:11:35-06:00, asqueaker at gmail.com wrote:
Hi Jaromir,
Here's a motivation example:
[1/0] on: Error do: [:ex | [ex signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
Would you expect this code to work and pick up the ZeroDivide handler?
...
The point or a use case is to provide additional (finer, more specific) handlers inside the general handler rather than wrap the general handler inside more specific handlers. More specific handlers can even be inside a method so the readability would not degrade.
I was able to do it by creating a new exception instance and signaling it:
[1/0] on: Error do: [: err | [err copy signal] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
I don't know about #copy, though, you might want to implement your own special #freshCopy that throws out the signalContext, handlerContext and outerContext, but the above "worked". :)
Precisely, it crossed my mind too and yes, it has to be a "fresh" copy with blank instance variables (except messageText). A simple copy fails tests with nested outer etc...
I've checked ANSI again and they say, quote: [5.5.3.1 messageText][...] Subsequent sends of of the message #messageText to a signaled exception generated by sending the message #signal to the receiver of this message [note: the receiver is an exception instance] will also return this value.
So what I'm actually looking for is this: (and it's equivalent to the "fresh" copy idea)
[1/0] on: Error do: [: err | [err class signal: err messageText] on: ZeroDivide do: [Transcript show: #ZeroDivide] ]
If I'm interpreting ANSI's intention correctly then we could update our #signal like this:
signal "Ask ContextHandlers in the sender chain to handle this signal. The default is to execute and return my defaultAction. Signaling an already signaled exception is interpreted as signaling a new exception of the same type with the same messageText"
- signalContext ifNotNil: [^self outer].
- signalContext ifNotNil: [^self copy signal: self messageText]. signalContext := thisContext contextTag. ^(thisContext nextHandlerContextForSignal: self) handleSignal: self
It was my idea last year to make subsequent sends of #signal to an already signaled exception equivalent to #outer and now I can see it was wrong and I'd like to really fix it this time :) All test are green, even the ones in Tests-jar.464.
Thanks, Chris, for discussing this.
best, Jaromir ^[^ -- Sent from Squeak Inbox Talk
squeak-dev@lists.squeakfoundation.org