eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'Query':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: Query


Inheritance:

   Object
   |
   +--GenericException
      |
      +--Notification
         |
         +--Query
            |
            +--AbortAllOperationWantedQuery
            |
            +--AbstractSourceFileWriter::MethodSourceRewriteQuery
            |
            +--BreakpointQuery
            |
            +--ClassRemoveChange::ClassBeingRemovedQuery
            |
            +--CompilationErrorHandlerQuery
            |
            +--DoNotShowCompilerWarningAgainActionQuery
            |
            +--DoNotShowCompilerWarningAgainForThisMethodActionQuery
            |
            +--DoNotShowCompilerWarningAgainForThisReceiverSelectorActionQuery
            |
            +--EditTextView::ExecutingMacroQuery
            |
            +--HTMLDocumentPainter::WidgetQuery
            |
            +--HTTPProxyQuery
            |
            +--ImageReader::EnforcedImageTypeQuery
            |
            +--IsDebuggingQuery
            |
            +--LoadInProgressQuery
            |
            +--Menu::NeedResourcesQuery
            |
            +--Model::ModelUpdateLockedQuery
            |
            +--Parser::AskForVariableTypeOfUndeclaredQuery
            |
            +--Parser::PossibleCorrectionsQuery
            |
            +--PluginSupport::StartParameterQuery
            |
            +--QueryWithoutDefault
            |
            +--UISpecification::UIMajorKeyBindingNameSpaceQuery
            |
            +--WindowGroup::LastEventQuery
            |
            +--WindowGroup::WindowGroupQuery

Package:
stx:libbasic
Category:
Kernel-Exceptions
Version:
rev: 1.16 date: 2017/07/23 12:00:37
user: cg
file: Query.st directory: libbasic
module: stx stc-classLibrary: libbasic
Author:
Claus Gittinger

Description:


Query is an abstract superclass for queries.

A query is an exception which by default proceeds if unhandled and returns
a default value.
As a class based reimplementation, it replaces and obsoletes the old 
QuerySignal instance based mechanism.

Note:
    Query does not add/refine any functionality from its superclass.
    It exists for the more descriptive class name only.

Queries are like exceptions, except that they are not accepted
by handlers for ordinary exceptions.
I.e. a handler for a normal exception will not handle a query. 
Thus, these bypass all normal exception handlers.

However, if unhandled, no error is raised, instead it is simply ignored
and nil is returned from the raise
(as opposed to normal exceptions, which raise an unhandled exception error).
Queries are also ignored, if a handler exists, but rejects.

The main use of Queries is to implement an upQuery, which works even 
if intermediate errorSignal handlers are present. 

Code deep down in the calling hierarchy can post such an up-Query to ask
for some information or to pass some information upward. 

For example, the activityNotification mechanism is built on top of this:
everyone can send such a notification which is either handled by someone
up in the hierarchy (to show it in the windows info area) or simply
ignored.

Using Queries for this (instead of regular Signals) helps in documenting
the intended usage of those signals.

Another use of queries is to provide additional information to
deeply nested methods, which is only required in the uncommon case;
or if another parameter is required by some method, which was not planned
for in the beginning, and you do not want to hand this value (via an
additional argument) through all intermediate levels.

A highly elegant solution to this problem is to provide a handler somewhere
at the top of the calling hierarchy, and raise an upQuery from whereever
that value is required.
A concrete application can be found in the windowGroup-lastEvent
queries. If anyone is interested in the windowEvent which was responible for 
being invoked, all he needs to do is to raise the lastEventQuerySignal, 
which returns that event.
No intermediate methods are required to know anything about that.
Another example is found in the way Metaclass asks for the nameSpace
when new classes are to be installed. A Browser may simply answer such
a query and provide a namespace (no need to pass that information down
the calling chain).

A final note (to C++ and Java fans):
    such upQueries are only possible, if the exception handling mechanism
    does not automatically unwind the stack for the handler invokation.
    Since the handler must be able to proceed the execution and return
    a value to the raiser ....
    ... another demonstration of why ST's exception mechanisms are superior.


Related information:

    Notification
    Warning
    Signal
    QuerySignal
    [``Exception handling and signals'']

Class protocol:

initialization
o  initialize
self initialize

misc ui support
o  iconInBrowserSymbol
( an extension from the stx:libtool package )
the browser will use this as index into the toolbariconlibrary

testing
o  isQuery
(comment from inherited method)
return true, if this is a query - always return false here


Instance protocol:

testing
o  isQuery


Examples:


    Query answer:'hello'
    do:[
        Transcript showCR:(Query query)
    ]
an up-query from a deeply nested operation to a higher level: the example below demonstrates that a Query is not an Error (i.e. the Error-handler does not interfere with Queries)
    |zero|

    zero := 0.
    Query handle:[:ex |
        Transcript showCR:'query'.
        ex proceedWith:true
    ] do:[
        'nesting'.
        [
            [
                Error handle:[:ex |
                    Transcript showCR:'some error: ' , ex errorString.
                    ex proceed
                ] do:[
                    [
                        1 // zero.  'an error which is caught in the handler'.
                        (Query query) == true ifTrue:[
                            Transcript showCR:'query says: ok'.
                        ] ifFalse:[
                            Transcript showCR:'query says: no'
                        ]
                    ] value
                ]
            ] value
        ] value
    ]
for lazy typists, a more compact interface for query-answerign is also provided (which is also easier to read):
    Query answer:true do:[
        'nesting'.
        [
            [
                (Query query) == true ifTrue:[
                    Transcript showCR:'query says: ok'.
                ] ifFalse:[
                    Transcript showCR:'query says: no'
                ]
            ] value
        ] value
    ]
an up-query from a deeply nested operation, for which there is no handler: (notice, this would not work with normal signals, which would raise another unhandled exception-exception; also notice the == check #raise's return value being true, instead of a simple ifTrue; this handles a nil-value from the unhandled query)
    |zero|

    zero := 0.
    [
        'nesting'.
        [
            [
                Error handle:[:ex |
                    Transcript showCR:'some error: ' , ex errorString.
                    ex proceed
                ] do:[
                    [
                        1 // zero.  'an error which is caught in the handler'.
                        (Query raise) == true ifTrue:[
                            Transcript showCR:'query says: ok'.
                        ] ifFalse:[
                            Transcript showCR:'query says: no'
                        ]
                    ] value
                ]
            ] value
        ] value
    ] value
counter-example, just to show that things would not work this way with regular signals:
    |signal|

    signal := Signal new.
    'nesting deeply'.
    [
        [
            [
                [
                    [
                        (signal raise) == true ifTrue:[
                            Transcript showCR:'query says: ok'.
                        ] ifFalse:[
                            Transcript showCR:'query says: no'
                        ]
                    ] value
                ] value
            ] value
        ] value
    ] value
except, by handling the unhandled exception (but we think, that querySignals are easier to use and better document the intent):
    |signal|

    signal := Signal new.
    'nesting deeply'.
    [
        [
            [
                [
                    [
                        Signal noHandlerSignal handle:[:ex |
                            ex proceedWith:nil
                        ] do:[
                            (signal raise) == true ifTrue:[
                                Transcript showCR:'query says: ok'.
                            ] ifFalse:[
                                Transcript showCR:'query says: no'
                            ]
                        ]
                    ] value
                ] value
            ] value
        ] value
    ] value


ST/X 7.1.0.0; WebServer 1.663 at exept.de:8081; Mon, 20 May 2019 23:13:52 GMT