added deferAfter: - defer exceptions until some later time
authorClaus Gittinger <cg@exept.de>
Fri, 15 Feb 2002 13:59:22 +0100
changeset 6396 74d5b0b588a6
parent 6395 2ad7a8e870ab
child 6397 311358bdeed6
added deferAfter: - defer exceptions until some later time
GenericException.st
Signal.st
SignalSet.st
--- a/GenericException.st	Fri Feb 15 13:49:04 2002 +0100
+++ b/GenericException.st	Fri Feb 15 13:59:22 2002 +0100
@@ -744,6 +744,44 @@
     "Created: / 23.7.1999 / 14:06:01 / stefan"
 !
 
+deferAfter:aBlock
+    "evaluate the argument, aBlock.
+     Ignore the receiver-signal during evaluation - i.e. simply continue,
+     but remember if the signal was raised.
+     After the block evaluation, finally raise the signal - if it was raised in the block.
+     If the signal is raised multiple times, only the first raises parameter is remembered,
+     and only a single raise is performed after the blocks evaluation.
+
+     Deferring makes sense for some signals, such as UserInterrupt or AbortSignal, 
+     which must occasionally be delayed temprarily until a save place is reached 
+     (especially when packages are sent across a communication channel, and you dont want
+      partial packages to be generated by user interruptions)."
+
+    |raisedSignal parameter result|
+
+    self handle:[:ex |
+        raisedSignal isNil ifTrue:[
+            raisedSignal := ex signal.
+            parameter := ex parameter.
+        ].
+        ex proceedWith:nil
+    ] do:[
+        result := aBlock value.
+    ].
+    raisedSignal notNil ifTrue:[
+        "/ the signal was raised during the execution
+        "/ above. Raise it now (delayed).
+        raisedSignal raiseWith:parameter.
+    ].
+    ^ result
+
+     "
+      UserInterrupt deferAfter:[
+         UserInterrupt raiseWith:'hello'
+      ]
+     "
+!
+
 handle:handleBlock do:aBlock
     "evaluate the argument, aBlock.
      If the receiver-signal is raised during evaluation,
@@ -2102,6 +2140,6 @@
 !GenericException class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/GenericException.st,v 1.60 2002-01-15 16:24:14 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/GenericException.st,v 1.61 2002-02-15 12:59:22 cg Exp $'
 ! !
 GenericException initialize!
--- a/Signal.st	Fri Feb 15 13:49:04 2002 +0100
+++ b/Signal.st	Fri Feb 15 13:59:22 2002 +0100
@@ -707,23 +707,61 @@
 !Signal methodsFor:'save evaluation'!
 
 catch:aBlock
-     "evaluate the argument, aBlock.
-      If the receiver-signal is raised during evaluation, abort
-      the evaluation and return true; otherwise return false. 
-      This is the catch & throw mechanism found in other languages,
-      where the returned value indicates if an exception occured."
+    "evaluate the argument, aBlock.
+     If the receiver-signal is raised during evaluation, abort
+     the evaluation and return true; otherwise return false. 
+     This is the catch & throw mechanism found in other languages,
+     where the returned value indicates if an exception occured."
+
+     |raiseOccurred|
+
+     raiseOccurred := false.
+     self handle:[:ex | raiseOccurred := true. ex return] do:aBlock.
+     ^ raiseOccurred
 
-      |raiseOccurred|
+     "
+      Object messageNotUnderstoodSignal catch:[
+         123 size open   
+      ]
+     "
+!
+
+deferAfter:aBlock
+    "evaluate the argument, aBlock.
+     Ignore the receiver-signal during evaluation - i.e. simply continue,
+     but remember if the signal was raised.
+     After the block evaluation, finally raise the signal - if it was raised in the block.
+     If the signal is raised multiple times, only the first raises parameter is remembered,
+     and only a single raise is performed after the blocks evaluation.
 
-      raiseOccurred := false.
-      self handle:[:ex | raiseOccurred := true. ex return] do:aBlock.
-      ^ raiseOccurred
+     Deferring makes sense for some signals, such as UserInterrupt or AbortSignal, 
+     which must occasionally be delayed temprarily until a save place is reached 
+     (especially when packages are sent across a communication channel, and you dont want
+      partial packages to be generated by user interruptions)."
+
+    |raisedSignal parameter result|
 
-      "
-       Object messageNotUnderstoodSignal catch:[
-          123 size open   
-       ]
-      "
+    self handle:[:ex |
+        raisedSignal isNil ifTrue:[
+            raisedSignal := ex signal.
+            parameter := ex parameter.
+        ].
+        ex proceedWith:nil
+    ] do:[
+        result := aBlock value.
+    ].
+    raisedSignal notNil ifTrue:[
+        "/ the signal was raised during the execution
+        "/ above. Raise it now (delayed).
+        raisedSignal raiseWith:parameter.
+    ].
+    ^ result
+
+     "
+      UserInterrupt deferAfter:[
+         UserInterrupt raiseWith:'hello'
+      ]
+     "
 !
 
 handle:handleBlock do:aBlock
@@ -806,23 +844,23 @@
 !
 
 ignoreIn:aBlock
-     "evaluate the argument, aBlock.
-      Ignore the receiver-signal during evaluation - i.e. simply continue. 
-      This makes only sense for some signals, such as UserInterrupt
-      or AbortSignal, because continuing after an exception without any cleanup
-      often leads to followup-errors."
+    "evaluate the argument, aBlock.
+     Ignore the receiver-signal during evaluation - i.e. simply continue. 
+     This makes only sense for some signals, such as UserInterrupt
+     or AbortSignal, because continuing after an exception without any cleanup
+     often leads to followup-errors."
 
-      ^ self handle:[:ex | ex proceedWith:nil] do:aBlock.
+     ^ self handle:[:ex | ex proceedWith:nil] do:aBlock.
 
-      "
-       Object messageNotUnderstoodSignal ignoreIn:[
-          123 size open   
-       ]
-      "
+     "
+      Object messageNotUnderstoodSignal ignoreIn:[
+         123 size open   
+      ]
+     "
 ! !
 
 !Signal class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Signal.st,v 1.85 2001-11-16 15:18:54 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Signal.st,v 1.86 2002-02-15 12:59:12 cg Exp $'
 ! !
--- a/SignalSet.st	Fri Feb 15 13:49:04 2002 +0100
+++ b/SignalSet.st	Fri Feb 15 13:59:22 2002 +0100
@@ -158,24 +158,62 @@
 !SignalSet methodsFor:'save evaluation'!
 
 catch:aBlock
-     "evaluate the argument, aBlock.
-      If any of the signals in the receiver is raised during evaluation, 
-      abort the evaluation and return true; otherwise return false. 
-      With the special anySignal, evaluation can be performed totally save 
-      from signals 
-      - but who (beside radical c++ fans) would do that ?"
+    "evaluate the argument, aBlock.
+     If any of the signals in the receiver is raised during evaluation, 
+     abort the evaluation and return true; otherwise return false. 
+     With the special anySignal, evaluation can be performed totally save 
+     from signals 
+     - but who (beside radical c++ fans) would do that ?"
+
+     |raiseOccurred|
+
+     raiseOccurred := false.
+     self handle:[:ex | raiseOccurred := true. ex return] do:aBlock.
+     ^ raiseOccurred
 
-      |raiseOccurred|
+     "
+      SignalSet anySignal catch:[
+         (#(1 2 3 4) at:5) / 0.0
+      ]
+     "
+!
+
+deferAfter:aBlock
+    "evaluate the argument, aBlock.
+     Ignore the receiver-signal during evaluation - i.e. simply continue,
+     but remember if the signal was raised.
+     After the block evaluation, finally raise the signal - if it was raised in the block.
+     If the signal is raised multiple times, only the first raises parameter is remembered,
+     and only a single raise is performed after the blocks evaluation.
 
-      raiseOccurred := false.
-      self handle:[:ex | raiseOccurred := true. ex return] do:aBlock.
-      ^ raiseOccurred
+     Deferring makes sense for some signals, such as UserInterrupt or AbortSignal, 
+     which must occasionally be delayed temprarily until a save place is reached 
+     (especially when packages are sent across a communication channel, and you dont want
+      partial packages to be generated by user interruptions)."
+
+    |raisedSignal parameter result|
 
-      "
-       SignalSet anySignal catch:[
-	  (#(1 2 3 4) at:5) / 0.0
-       ]
-      "
+    self handle:[:ex |
+        raisedSignal isNil ifTrue:[
+            raisedSignal := ex signal.
+            parameter := ex parameter.
+        ].
+        ex proceedWith:nil
+    ] do:[
+        result := aBlock value.
+    ].
+    raisedSignal notNil ifTrue:[
+        "/ the signal was raised during the execution
+        "/ above. Raise it now (delayed).
+        raisedSignal raiseWith:parameter.
+    ].
+    ^ result
+
+     "
+      UserInterrupt deferAfter:[
+         UserInterrupt raiseWith:'hello'
+      ]
+     "
 !
 
 handle:handleBlock do:aBlock
@@ -233,26 +271,26 @@
 !
 
 ignoreIn:aBlock
-     "evaluate the argument, aBlock.
-      Ignore the any signals from the receiver during evaluation - i.e. simply
-      continue. This makes only sense for some signals, such as UserInterrupt
-      or AbortSignals, because continuing after an exception without any cleanup
-      will often lead to followup-errors."
+    "evaluate the argument, aBlock.
+     Ignore the any signals from the receiver during evaluation - i.e. simply
+     continue. This makes only sense for some signals, such as UserInterrupt
+     or AbortSignals, because continuing after an exception without any cleanup
+     will often lead to followup-errors."
 
-      ^ self handle:[:ex | ex proceedWith:nil] do:aBlock.
+     ^ self handle:[:ex | ex proceedWith:nil] do:aBlock.
 
-      "
-       SignalSet anySignal ignoreIn:[
-          123 size open   
-       ]
-      "
+     "
+      SignalSet anySignal ignoreIn:[
+         123 size open   
+      ]
+     "
 
-    "Created: / 27.1.1997 / 20:32:50 / cg"
-    "Modified: / 4.3.1998 / 16:36:30 / cg"
+     "Created: / 27.1.1997 / 20:32:50 / cg"
+     "Modified: / 4.3.1998 / 16:36:30 / cg"
 ! !
 
 !SignalSet class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/SignalSet.st,v 1.34 2001-03-23 13:43:18 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/SignalSet.st,v 1.35 2002-02-15 12:59:15 cg Exp $'
 ! !