Query.st
changeset 4464 cec93c942c14
parent 4446 4da4e51fc1ab
child 4466 9cba6f4ecec4
equal deleted inserted replaced
4463:60cc202629e2 4464:cec93c942c14
       
     1 'From Smalltalk/X, Version:3.5.3 on 26-jul-1999 at 00:02:41'                    !
       
     2 
     1 Exception subclass:#Query
     3 Exception subclass:#Query
     2 	instanceVariableNames:''
     4 	instanceVariableNames:''
     3 	classVariableNames:''
     5 	classVariableNames:''
     4 	poolDictionaries:''
     6 	poolDictionaries:''
     5 	category:'Kernel-Exceptions'
     7 	category:'Kernel-Exceptions'
    18         Signal QuerySignal
    20         Signal QuerySignal
    19 "
    21 "
    20 
    22 
    21 !
    23 !
    22 
    24 
    23 examples
    25 examples 
    24 "
    26 "
    25     examples to be added.
    27   an up-query from a deeply nested operation to a higher level:
    26 								[exBegin]
    28                                                                         [exBegin]
    27     ... add code fragment for 
    29     |zero|
    28     ... executable example here ...
    30 
    29 								[exEnd]
    31     zero := 0.
       
    32     Query handle:[:ex |
       
    33         Transcript showCR:'query'.
       
    34         ex proceedWith:true
       
    35     ] do:[
       
    36         'nesting'.
       
    37         [
       
    38             [
       
    39                 Object errorSignal handle:[:ex |
       
    40                     Transcript showCR:'some error: ' , ex errorString.
       
    41                     ex proceed
       
    42                 ] do:[
       
    43                     [
       
    44                         1 // zero.  'an error which is caught in the handler'.
       
    45                         (Query query) == true ifTrue:[
       
    46                             Transcript showCR:'query says: ok'.
       
    47                         ] ifFalse:[
       
    48                             Transcript showCR:'query says: no'
       
    49                         ]
       
    50                     ] value
       
    51                 ]
       
    52             ] value
       
    53         ] value
       
    54     ]
       
    55                                                                         [exEnd]
       
    56   for lazy typists, a more compact interface is also provided
       
    57   (which is also easier to read):
       
    58                                                                         [exBegin]
       
    59     Query answer:true do:[
       
    60         'nesting'.
       
    61         [
       
    62             [
       
    63                 (Query query) == true ifTrue:[
       
    64                     Transcript showCR:'query says: ok'.
       
    65                 ] ifFalse:[
       
    66                     Transcript showCR:'query says: no'
       
    67                 ]
       
    68             ] value
       
    69         ] value
       
    70     ]
       
    71                                                                         [exEnd]
       
    72   an up-query from a deeply nested operation, for which there
       
    73   is no handler:
       
    74   (notice, this would not work with normal signals, which would raise
       
    75    another unhandled exception-exception;
       
    76    also notice the == check #raise's return value being true,
       
    77    instead of a simple ifTrue; this handles a nil-value from
       
    78    the unhandled query)
       
    79                                                                         [exBegin]
       
    80     |zero|
       
    81 
       
    82     zero := 0.
       
    83     [
       
    84         'nesting'.
       
    85         [
       
    86             [
       
    87                 Object errorSignal handle:[:ex |
       
    88                     Transcript showCR:'some error: ' , ex errorString.
       
    89                     ex proceed
       
    90                 ] do:[
       
    91                     [
       
    92                         1 // zero.  'an error which is caught in the handler'.
       
    93                         (Query raise) == true ifTrue:[
       
    94                             Transcript showCR:'query says: ok'.
       
    95                         ] ifFalse:[
       
    96                             Transcript showCR:'query says: no'
       
    97                         ]
       
    98                     ] value
       
    99                 ]
       
   100             ] value
       
   101         ] value
       
   102     ] value
       
   103                                                                          [exEnd]
       
   104   counter-example, just to show that things would not work this way
       
   105   with regular signals:
       
   106                                                                         [exBegin]
       
   107     |signal|
       
   108 
       
   109     signal := Signal new.
       
   110     'nesting deeply'.
       
   111     [
       
   112         [
       
   113             [
       
   114                 [
       
   115                     [
       
   116                         (signal raise) == true ifTrue:[
       
   117                             Transcript showCR:'query says: ok'.
       
   118                         ] ifFalse:[
       
   119                             Transcript showCR:'query says: no'
       
   120                         ]
       
   121                     ] value
       
   122                 ] value
       
   123             ] value
       
   124         ] value
       
   125     ] value
       
   126                                                                          [exEnd]
       
   127 
       
   128    except, by handling the unhandled exception
       
   129    (but we think, that querySignals are easier to use and
       
   130     better document the intent):
       
   131                                                                         [exBegin]
       
   132     |signal|
       
   133 
       
   134     signal := Signal new.
       
   135     'nesting deeply'.
       
   136     [
       
   137         [
       
   138             [
       
   139                 [
       
   140                     [
       
   141                         Signal noHandlerSignal handle:[:ex |
       
   142                             ex proceedWith:nil
       
   143                         ] do:[
       
   144                             (signal raise) == true ifTrue:[
       
   145                                 Transcript showCR:'query says: ok'.
       
   146                             ] ifFalse:[
       
   147                                 Transcript showCR:'query says: no'
       
   148                             ]
       
   149                         ]
       
   150                     ] value
       
   151                 ] value
       
   152             ] value
       
   153         ] value
       
   154     ] value
       
   155                                                                          [exEnd]
    30 "
   156 "
       
   157 
    31 !
   158 !
    32 
   159 
    33 history
   160 history
    34     "Created: / 23.7.1999 / 14:16:16 / stefan"
   161     "Created: / 23.7.1999 / 14:16:16 / stefan"
    35 ! !
   162 ! !
    39 answer:someAnswer do:aBlock
   166 answer:someAnswer do:aBlock
    40      "evaluate the argument, aBlock.
   167      "evaluate the argument, aBlock.
    41       If the receiver is queried during evaluation, answer with someAnswer.
   168       If the receiver is queried during evaluation, answer with someAnswer.
    42       This is a wrapper for #handle:do: for lazy typists; no new functionality."
   169       This is a wrapper for #handle:do: for lazy typists; no new functionality."
    43 
   170 
    44       ^ self handle:[:ex | ex proceedWith:someAnswer] do:aBlock.
   171       thisContext markForHandle.
       
   172       aBlock value.
    45 
   173 
    46       "
   174       "
    47        Query answer:true do:[
   175        Query answer:true do:[
    48           Transcript showCR:'query answers: ' , (Query query printString).
   176           Transcript showCR:'query answers: ' , (Query query printString).
    49        ]
   177        ]
    58        ]
   186        ]
    59       "
   187       "
    60 
   188 
    61     "Created: / 10.7.1996 / 15:08:20 / cg"
   189     "Created: / 10.7.1996 / 15:08:20 / cg"
    62     "Modified: / 14.10.1996 / 16:59:18 / cg"
   190     "Modified: / 14.10.1996 / 16:59:18 / cg"
    63     "Modified: / 23.7.1999 / 15:26:13 / stefan"
   191     "Modified: / 25.7.1999 / 23:12:19 / stefan"
    64 ! !
   192 ! !
    65 
   193 
    66 !Query class methodsFor:'queries'!
   194 !Query class methodsFor:'queries'!
    67 
   195 
    68 accepts:aSignal
   196 accepts:aSignal
    95     ^ super raiseRequest
   223     ^ super raiseRequest
    96 
   224 
    97     "Created: / 23.7.1999 / 15:16:03 / stefan"
   225     "Created: / 23.7.1999 / 15:16:03 / stefan"
    98 !
   226 !
    99 
   227 
       
   228 handlerForSignal:signal context:theContext originator:originator
       
   229     "answer the handler block for the signal from originator.
       
   230      The block is retrieved from aContext.
       
   231      Answer nil if the signal is not handled"
       
   232 
       
   233     |arg|
       
   234 
       
   235     theContext selector == #'answer:do:' ifTrue:[
       
   236         (self accepts:signal) ifTrue:[
       
   237             arg := theContext argAt:1.
       
   238             ^ [:ex| ex proceedWith:arg].
       
   239         ]
       
   240     ] ifFalse:[
       
   241         ^ super handlerForSignal:signal context:theContext originator:originator.
       
   242     ].
       
   243 
       
   244     ^ nil
       
   245 
       
   246     "Created: / 25.7.1999 / 23:11:55 / stefan"
       
   247 !
       
   248 
   100 isQuerySignal
   249 isQuerySignal
   101 
   250 
   102     ^ true
   251     ^ true
   103 
   252 
   104     "Created: / 23.7.1999 / 14:59:50 / stefan"
   253     "Created: / 23.7.1999 / 14:59:50 / stefan"
   105 !
   254 !
   106 
       
   107 raise
       
   108     "QuerySignals are proceedable by definition,
       
   109      so they should be raised with #query or #raiseRequest"
       
   110 
       
   111     ^ self shouldNotImplement
       
   112 
       
   113     "Created: / 23.7.1999 / 15:19:17 / stefan"
       
   114 !
       
   115 
       
   116 raiseRequest
       
   117     "redefined to use #query"
       
   118 
       
   119     ^ self query
       
   120 
       
   121     "Created: / 23.7.1999 / 15:19:35 / stefan"
       
   122 ! !
       
   123 
       
   124 !Query class methodsFor:'query'!
       
   125 
   255 
   126 query
   256 query
   127     "raise the query - return the handlers value, or the default
   257     "raise the query - return the handlers value, or the default
   128      value, if there is no handler.
   258      value, if there is no handler.
   129      Invoking the handler is exactly the functionality of Signal>>raiseRequest,
   259      Invoking the handler is exactly the functionality of Signal>>raiseRequest,
   131 
   261 
   132     |con s|
   262     |con s|
   133 
   263 
   134     con := thisContext sender.
   264     con := thisContext sender.
   135     [con notNil] whileTrue:[
   265     [con notNil] whileTrue:[
   136         con := con findNextContextWithSelector:#doRaise 
   266         con := con findSpecialHandle:true raise:true.
   137                                             or:#handle:do:
       
   138                                             or:#handle:from:do:.
       
   139         con notNil ifTrue:[
   267         con notNil ifTrue:[
   140             (con selector == #handle:do:) ifFalse:[
   268             (con selector == #answer:do:) ifFalse:[
   141                 ^ super raiseRequest
   269                 ^ super raiseRequest
   142             ].
   270             ].
   143             (s := con receiver) == self ifTrue:[
   271             (s := con receiver) == self ifTrue:[
   144                 "/ found a non-busy handler ...
       
   145                 "/ if its sender is a #answer context,
       
   146                 "/ fetch its value quickly from it.
       
   147                 con := con sender.
       
   148                 con selector == #answer:do: ifFalse:[
       
   149                     con receiver == self ifFalse:[
       
   150                         ^ super raiseRequest
       
   151                     ]
       
   152                 ].
       
   153                 ^ con argAt:1
   272                 ^ con argAt:1
   154             ] ifFalse:[
   273             ] ifFalse:[
   155                 (s accepts:self) ifTrue:[
   274                 (s accepts:self) ifTrue:[
   156                     ^ super raiseRequest
   275                     ^ super raiseRequest
   157                 ]
   276                 ]
   160     ].
   279     ].
   161     "/ no handler found - return the default value
   280     "/ no handler found - return the default value
   162     ^ self defaultAnswer
   281     ^ self defaultAnswer
   163 
   282 
   164     "Modified: / 15.6.1998 / 21:27:37 / cg"
   283     "Modified: / 15.6.1998 / 21:27:37 / cg"
   165     "Modified: / 23.7.1999 / 15:19:59 / stefan"
   284     "Modified: / 25.7.1999 / 23:15:16 / stefan"
       
   285 !
       
   286 
       
   287 raise
       
   288     "QuerySignals are proceedable by definition,
       
   289      so they should be raised with #query or #raiseRequest"
       
   290 
       
   291     ^ self shouldNotImplement
       
   292 
       
   293     "Created: / 23.7.1999 / 15:19:17 / stefan"
       
   294 !
       
   295 
       
   296 raiseRequest
       
   297     "redefined to use #query"
       
   298 
       
   299     ^ self query
       
   300 
       
   301     "Created: / 25.7.1999 / 23:25:59 / stefan"
   166 ! !
   302 ! !
   167 
   303 
   168 !Query methodsFor:'default actions'!
   304 !Query methodsFor:'default actions'!
   169 
   305 
   170 action
   306 action
   177 ! !
   313 ! !
   178 
   314 
   179 !Query class methodsFor:'documentation'!
   315 !Query class methodsFor:'documentation'!
   180 
   316 
   181 version
   317 version
   182     ^ '$Header: /cvs/stx/stx/libbasic/Query.st,v 1.1 1999-07-23 17:53:13 stefan Exp $'
   318     ^ '$Header: /cvs/stx/stx/libbasic/Query.st,v 1.2 1999-07-28 07:53:26 stefan Exp $'
   183 ! !
   319 ! !