SignalSet.st
author claus
Mon, 10 Oct 1994 01:29:28 +0100
changeset 159 514c749165c3
parent 95 d22739a0c6e9
child 259 a5c9efa2ac05
permissions -rw-r--r--
*** empty log message ***

"
 COPYRIGHT (c) 1993 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

IdentitySet subclass:#SignalSet
	 instanceVariableNames:''
	 classVariableNames:'SetOfAnySignal'
	 poolDictionaries:''
	 category:'Kernel-Exceptions'
!

SignalSet comment:'
COPYRIGHT (c) 1993 by Claus Gittinger
	      All Rights Reserved

$Header: /cvs/stx/stx/libbasic/SignalSet.st,v 1.9 1994-10-10 00:28:22 claus Exp $
'!

!SignalSet class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1993 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

version
"
$Header: /cvs/stx/stx/libbasic/SignalSet.st,v 1.9 1994-10-10 00:28:22 claus Exp $
"
!

documentation
"
    SignalSet allows catching of multiple signals. A SignalSet consists of
    a number of signals and also implements the #handle:do: and #catch: methods
    just as signals do. 
    However, any signal from the SignalSet will, if signalled, lead into the handler.

    There is also a special signalSet, which can be used to catch any
    signal in the system - but this should no longer be used, since catching
    Object>>errorSignal has now the same effect.

    For more detail, see comment in Signal and examples in doc/coding.

    Notice: SignalSets are not needed when a group of children of a common signal
    (such as arithmeticSignal) is to be handled; the parent signal of those will
    also handle all children.
    Use signalSets if totally unrelated signals should be handled by one common
    handler.
"
! !

!SignalSet class methodsFor:'instance creation'!

anySignal
    "return a special signalSet for catching any signal.
     Obsolete; use Object>>errorSignal for that purpose."

    SetOfAnySignal isNil ifTrue:[
	SetOfAnySignal := self basicNew
    ].
    ^ SetOfAnySignal
! !

!SignalSet methodsFor:'save evaluation'!

handle:handleBlock do:aBlock
    "evaluate the argument, aBlock.
     If any of the signals in the receiver is raised during evaluation,
     evaluate the handleBlock passing it an Exception argument.
     The handler may decide how to react to the signal by sending
     a corresponding message to the exception (see there).
     If the signal is not raised, return the value of evaluating
     aBlock."

     ^ aBlock value  "the real logic is in raise/Exception"

      "
       SignalSet anySignal handle:[:ex |
	  ex errorString print. ' occured in: ' print. ex suspendedContext printNL.
	  ex return
       ] do:[
	  (#(1 2 3 4) at:5) / 0.0
       ]
      "
!

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 ?"

      |raiseOccurred|

      raiseOccurred := false.
      self handle:[:ex | raiseOccurred := true. ex return] do:aBlock.
      ^ raiseOccurred

      "
       SignalSet anySignal catch:[
	  (#(1 2 3 4) at:5) / 0.0
       ]
      "
!

ignore: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 AbortSignals, because continuing after an exception without any cleanup
      will often lead to followup-errors."

      ^ self handle:[:ex | ex proceed] do:aBlock.

      "
       SignalSet anySignal ignore:[
	  123 size open   
       ]
      "
! !

!SignalSet methodsFor:'queries'!

accepts:aSignal
    "return true, if the receiver accepts the argument, aSignal.
     (i.e. if any of the receivers elements is aSignal or a parent of it).
     False otherwise. he special anySet accepts any signal."

    (self == SetOfAnySignal) ifTrue:[^ true].
    self do:[:sig | (sig accepts:aSignal) ifTrue:[^ true]].
    ^ false
!

includes:aSignal
    "return true, if the receiver contains the argument, aSignal.
     The special any-Set includes every signal."

    (self == SetOfAnySignal) ifTrue:[
	^ aSignal isKindOf:Signal
    ].
    ^ super includes:aSignal
! !