29.11. Dependent Maintenance

29.11.1. Protocol
29.11.1.1. Generic Function CLOS:UPDATE-DEPENDENT
29.11.1.2. Generic Function CLOS:ADD-DEPENDENT
29.11.1.3. Generic Function CLOS:REMOVE-DEPENDENT
29.11.1.4. Generic Function CLOS:MAP-DEPENDENTS

It is convenient for portable metaobjects to be able to memoize information about other metaobjects, portable or otherwise. Because class and generic function metaobjects can be reinitialized, and generic function metaobjects can be modified by adding and removing methods, a means must be provided to update this memoized information.

The dependent maintenance protocol supports this by providing a way to register an object which should be notified whenever a class or generic function is modified. An object which has been registered this way is called a dependent of the class or generic function metaobject. The dependents of class and generic function metaobjects are maintained with CLOS:ADD-DEPENDENT and CLOS:REMOVE-DEPENDENT. The dependents of a class or generic function metaobject can be accessed with CLOS:MAP-DEPENDENTS. Dependents are notified about a modification by calling CLOS:UPDATE-DEPENDENT. (See the specification of CLOS:UPDATE-DEPENDENT for detailed description of the circumstances under which it is called.)

To prevent conflicts between two portable programs, or between portable programs and the implementation, portable code must not register metaobjects themselves as dependents. Instead, portable programs which need to record a metaobject as a dependent, should encapsulate that metaobject in some other kind of object, and record that object as the dependent. The results are undefined if this restriction is violated.

This example shows a general facility for encapsulating metaobjects before recording them as dependents. The facility defines a basic kind of encapsulating object: an updater. Specializations of the basic class can be defined with appropriate special updating behavior. In this way, information about the updating required is associated with each updater rather than with the metaobject being updated.

Updaters are used to encapsulate any metaobject which requires updating when a given class or generic function is modified. The function record-updater is called to both create an updater and add it to the dependents of the class or generic function. Methods on the generic function CLOS:UPDATE-DEPENDENT, specialized to the specific class of updater do the appropriate update work.

(defclass updater ()
  ((dependent :initarg :dependent :reader dependent)))

(defun record-updater (class dependee dependent &REST initargs)
  (let ((updater (apply #'make-instance class :dependent dependent
                                              initargs)))
    (add-dependent dependee updater)
    updater))

A flush-cache-updater simply flushes the cache of the dependent when it is updated.

(defclass flush-cache-updater (updater) ())

(defmethod update-dependent (dependee (updater flush-cache-updater) &REST args)
  (declare (ignore args))
  (flush-cache (dependent updater)))

29.11.1. Protocol

29.11.1.1. Generic Function CLOS:UPDATE-DEPENDENT

Syntax
(CLOS:UPDATE-DEPENDENT metaobject dependent &REST initargs)
Arguments
metaobject
a class metaobject or a generic function metaobject - the metaobject being reinitialized or otherwise modified.
dependent
an object - the dependent being updated.
initargs
a list of the initialization arguments for the metaobject redefinition.
Values
The values returned by this generic function are unspecified.
Purpose

This generic function is called to update a dependent of metaobject.

When a class or a generic function is reinitialized each of its dependents is updated. The initargs argument to CLOS:UPDATE-DEPENDENT is the set of initialization arguments received by REINITIALIZE-INSTANCE.

When a method is added to a generic function, each of the generic function's dependents is updated. The initargs argument is a list of two elements: the symbol ADD-METHOD, and the method that was added.

When a method is removed from a generic function, each of the generic function's dependents is updated. The initargs argument is a list of two elements: the symbol REMOVE-METHOD, and the method that was removed.

In each case, CLOS:MAP-DEPENDENTS is used to call CLOS:UPDATE-DEPENDENT on each of the dependents. So, for example, the update of a generic function's dependents when a method is added could be performed by the following code:

(CLOS:MAP-DEPENDENTS generic-function
                     #'(lambda (dep)
                         (CLOS:UPDATE-DEPENDENT generic-function
                                                dep 'add-method new-method)))

Remarks. See Section 29.11, “Dependent Maintenance” for remarks about the use of this facility.

29.11.1.2. Generic Function CLOS:ADD-DEPENDENT

Syntax
(CLOS:ADD-DEPENDENT metaobject dependent)
Arguments
metaobject
a class metaobject or a generic function metaobject.
dependent
an object.
Values
The values returned by this generic function are unspecified.
Purpose

This generic function adds dependent to the dependents of metaobject. If dependent is already in the set of dependents it is not added again (no ERROR is SIGNALed).

The generic function CLOS:MAP-DEPENDENTS can be called to access the set of dependents of a class or generic function. The generic function CLOS:REMOVE-DEPENDENT can be called to remove an object from the set of dependents of a class or generic function. The effect of calling CLOS:ADD-DEPENDENT or CLOS:REMOVE-DEPENDENT while a call to CLOS:MAP-DEPENDENTS on the same class or generic function is in progress is unspecified.

The situations in which CLOS:ADD-DEPENDENT is called are not specified.

Methods

(CLOS:ADD-DEPENDENT (class STANDARD-CLASS) dependent)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

(CLOS:ADD-DEPENDENT (class CLOS:FUNCALLABLE-STANDARD-CLASS) dependent)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

(CLOS:ADD-DEPENDENT (generic-function STANDARD-GENERIC-FUNCTION) dependent)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

Remarks. See Section 29.11, “Dependent Maintenance” for remarks about the use of this facility.

29.11.1.3. Generic Function CLOS:REMOVE-DEPENDENT

Syntax
(CLOS:REMOVE-DEPENDENT metaobject dependent)
Arguments
metaobject
a class metaobject or a generic function metaobject.
dependent
an object.
Values
The values returned by this generic function are unspecified.
Purpose

This generic function removes dependent from the dependents of metaobject. If dependent is not one of the dependents of metaobject, no ERROR is SIGNALed.

The generic function CLOS:MAP-DEPENDENTS can be called to access the set of dependents of a class or generic function. The generic function CLOS:ADD-DEPENDENT can be called to add an object from the set of dependents of a class or generic function. The effect of calling CLOS:ADD-DEPENDENT or CLOS:REMOVE-DEPENDENT while a call to CLOS:MAP-DEPENDENTS on the same class or generic function is in progress is unspecified.

The situations in which CLOS:REMOVE-DEPENDENT is called are not specified.

Methods

(CLOS:REMOVE-DEPENDENT (class STANDARD-CLASS) dependent)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

(CLOS:REMOVE-DEPENDENT (class CLOS:FUNCALLABLE-STANDARD-CLASS) dependent)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

(CLOS:REMOVE-DEPENDENT (class STANDARD-GENERIC-FUNCTION) dependent)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

Remarks. See Section 29.11, “Dependent Maintenance” for remarks about the use of this facility.

29.11.1.4. Generic Function CLOS:MAP-DEPENDENTS

Syntax
(CLOS:MAP-DEPENDENTS metaobject function)
Arguments
metaobject
a class metaobject or a generic function metaobject.
function
a function which accepts one argument.
Values
The values returned by this generic function are unspecified.
Purpose
This generic function applies function to each of the dependents of metaobject. The order in which the dependents are processed is not specified, but function is applied to each dependent once and only once. If, during the mapping, CLOS:ADD-DEPENDENT or CLOS:REMOVE-DEPENDENT is called to alter the dependents of metaobject, it is not specified whether the newly added or removed dependent will have function applied to it.

Methods

(CLOS:MAP-DEPENDENTS (metaobject STANDARD-CLASS) function)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

(CLOS:MAP-DEPENDENTS (metaobject CLOS:FUNCALLABLE-STANDARD-CLASS) function)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

(CLOS:MAP-DEPENDENTS (metaobject STANDARD-GENERIC-FUNCTION) function)

No behavior is specified for this method beyond that which is specified for the generic function.

This method cannot be overridden unless the following methods are overridden as well:

Remarks. See Section 29.11, “Dependent Maintenance” for remarks about the use of this facility.


These notes document CLISP version 2.49Last modified: 2010-07-07