Variable callbacks are functions associated with global variables, including dependencies, (or, indeed, functions or names that do not yet have a value) that are called just before or after Assignments or certain Selective Assignments are made to those variables. Variable callback functions are the subject of this chapter and will usually be spoken of as just "callback functions". Callbacks are particularly important for asynchronous events, such as in screen management in the s context, for tracking user actions; see "Interprocess Communication: adap", and "Introduction to Screen Management" and the chapters that follow it.A mapped file mf can have an associated callback, but that callback is associated with the variable mf, not the underlying file. A change to the file through another mapped variable, in the same process or not, or by any other means than an assignment to mf will not trigger a callback for mf.
In A+, variable callback functions (as distinct from event callback functions) have the same basic syntax (variations are discussed below):
cfn{s;d;i;p;c;v}For example, if the function cfn is associated with the global variable price defined in the context comp, then when price changes, cfn is automatically called with arguments supplied by A+:When cfn is called because of an Assignment of a global variable, the change to that variable can be described in terms of the arguments to cfn as
- s is static data (see below);
- d is the new value, i.e., the value of the righthand side of the Assignment triggering the callback;
- i is an index or set of indices (left argument to Choose - see p);
- p is a path (left argument to Pick) such that i#pØprice is the subarray that changed;
- c is the name of the context, in the form of a symbol, `comp; and
- v is the name of the global variable in the form of a symbol,`price.
(i#pØc%v)ûd if i is nested, or
(i#,pØc%v)ûd if i is simple, or
(pØc%v)[,]ûd if i is out of range for c%v before this assignment.The last case involves the Append form of Selective Assignment and i is the set of indices in pØc%v (after the assignment) of the appended elements.
The first argument of a callback function is called the static data. Static data is specified when the association between a variable and a callback function is established. Typically, the static data is any constant extra information needed to process the change in the associated variable.
A callback function can have anywhere from zero to six arguments, but no matter how many it has, their meaning from left to right is the same as above. For example, if f{a;b;c} is a callback function, then a is static data, b is new data, and c is an index.
The other type of callback is the event callback. Event callback functions have the basic syntax cfn{s;c;v} where the names s, c, and v have the same significance as above. An event callback function may have from zero to three arguments; the arguments are positional. See the chapters mentioned in the first paragraph of this chapter and especially "Attributes with Callbacks".
A+ provides the Set Callback (_scb) and Set Preset Callback (_spcb) system functions for establishing and removing the association between a global variable and a callback function. Set Callback is discussed here, and Set Preset Callback below. The left argument is a symbol naming the global variable. The right argument is a pair of the form (fcn_name;static_data), where static_data is the static data (perhaps Null), and fcn_name is a function expression, a name entered without backquote or quotes. Thus the first element of this argument, with the enclosure by strand, is a function scalar and not a name, so this association is unaffected by any later changes to the meaning of the name of fcn_name. For example:cbf{s;d;i;p;c;v}:Õ(s;d;i;p;c;v) ã A callback function. `a _scb (cbf;'-- a --') ã Call cbf whenever a is specified. aû92 ã Specify a and see the arguments to the callback function. < -- a -- ã Static data s < 92 ã New data d < ã Index i is null. < ã Path p is null. < ` ã c names the root context. < `a ã v names the variable a aû10 20 30 40 ã Set a and see args to cbf < -- a -- < 10 20 30 40 < < < ` < `a a[1]û200 ã Indexed Assignment. < -- a -- < 200 < 1 < < ` < `a `a _scb (;) ã Remove the callback on a and aû999 ã see no callback. a 999 $cx ctx ã Set new context. bû(`scalar`vector`matrix; (3.14; 'abcdef'; É3 2)) `b _scb (.cbf;'-- b --') ã Call cbf when b changes. (1;0)#`matrixØb ã Pick-Choose 2 from the matrix. 2 ((1;0)#`matrixØb)û22 ã Change the 2 to a 22. < -- b -- < 22 < < 1 ã Index (1;0) < 0 < `matrix ã Path `matrix < `ctx < `b (1;0)#`matrixØb ã Pick-Choose 22 from the matrix. 22
Any form of Selective Assignment can cause a callback function to be executed. Taking the last example from the previous section and continuing:(1 0/b)û<`Scalar`Vector`Matrix < -- b -- < < `Scalar `Vector `Matrix < 0 ã Index is 0. < ã Path is Null. < `ctx < `b b ã And the change was made. < `Scalar `Vector `Matrix < < 3.14 < abcdef < 0 1 22 3 4 5The next example shows an Append Selective Assignment triggering a callback:xûÉ10 `x _scb (.cbf;'-- x --') x[,]û100 200 < -- x -- ã The callback was triggered. < 100 200 < < 10 11 < < `ctx < `x
There may be times when you want to avoid callbacks - for example, when you are clearing a suspension and with normal execution many more suspensions would occur because of errors in callback functions. You can use the $Sf command for that purpose. See "Callback Flag" and note the warnings there.
It is important to know that callbacks established by _scb are called after the associated global variables have changed. This can be verified by defining a callback function that displays the value of the associated variable. When the function is called, the new value of the variable will be displayed, not the old. Note that the callback argument d is not necessarily this new value; d is, rather, the explicit result of the Assignment.An ordinary callback function on a dependency is not called when the dependency definition is evaluated, although a preset callback function is. Similarly, during a callback on a dependency, the dependent variable's value is not marked invalid by any change the function makes in a variable on which the dependency depends.
It is also possible to establish callbacks that are called just before the value of a variable is changed, so that the change can be validated. To do so, use the system function _spcb, which takes the same arguments as _scb.The differences between callback functions established by _spcb and _scb are:
Since preset callbacks are used for validating new values of global variables, the following rules should be followed in their definitions:
- preset callback functions on dependencies are called when either a dependent variable is assigned a value or the dependency is evaluated, whereas callback functions are called only when the dependent variable is assigned a value;
- _spcb{y;x} causes the callback function specified in x to be called just before the value of the global variable named in y is changed;
- preset callback functions are used to validate new values for global variables and they therefore must return meaningful results (namely, the validated data), while callback functions need not, their explicit results being ignored;
- for the Append form of Selective Assignment, the indices i are not valid for a preset callback, since the appending has not yet been done.
- if a new value is valid, set the result of the preset callback function to that value;
- if the indices i are not null, do not change the shape of d or you will get a length error report;
- if a new value is invalid, signal an error (see "Signal"); the value of the global variable will remain unchanged.
The evaluation of a dependency can trigger a callback on the dependent variable, one that was established by the Set Preset Callback function - but not one that was established by the Set Callback function. The callback occurs after the definition body has been evaluated and before the dependent variable is set. The second argument to the callback is the result of evaluating the definition body, and the result of the callback is the value to which the dependent variable is set - or to which the items of the dependent variable are set, in the itemwise case.Moreover, when a dependency is evaluated, callbacks of either kind can be triggered by assignments to other variables during the evaluation. These callbacks may mark saved values of other dependencies invalid.
A dependency that is currently being evaluated, however, or indeed a dependency whose callback function is being executed is marked as being in that state, and so its value will not be marked invalid while the evaluation or execution is going on.
Evaluation of a dependency is not complete until all callbacks, including any on the dependent variable, have been finished. See "Dependencies" for an example.
An error that occurs during the execution of a callback within the execution of a Protected Execute or Monadic do is reported in the result of the protected execution.
doc@aplusdev.org | © Copyright 19952008 Morgan Stanley Dean Witter & Co. All rights reserved. |