29.11. Dependent Maintenance
Prev | Chapter 29. Meta-Object Protocol | Next

## 29.11. Dependent Maintenance

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 or 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 is 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 or generic function metaobject
  `dependent`
    an object
Values
  The values returned by this generic function is 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 `SIGNAL`ed).

  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:REMOVE-DEPENDENT` (`STANDARD-CLASS` `T`)`
  - ``CLOS:MAP-DEPENDENTS` (`STANDARD-CLASS` `T`)`
`(`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:REMOVE-DEPENDENT` (`CLOS:FUNCALLABLE-STANDARD-CLASS` `T`)`
  - ``CLOS:MAP-DEPENDENTS` (`CLOS:FUNCALLABLE-STANDARD-CLASS` `T`)`
`(`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:

  - ``CLOS:REMOVE-DEPENDENT` (`STANDARD-GENERIC-FUNCTION` `T`)`
  - ``CLOS:MAP-DEPENDENTS` (`STANDARD-GENERIC-FUNCTION` `T`)`

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 or generic function metaobject
  `dependent`
    an object
Values
  The values returned by this generic function is 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 `SIGNAL`ed.

  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:ADD-DEPENDENT` (`STANDARD-CLASS` `T`)`
  - ``CLOS:MAP-DEPENDENTS` (`STANDARD-CLASS` `T`)`
`(`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:ADD-DEPENDENT` (`CLOS:FUNCALLABLE-STANDARD-CLASS` `T`)`
  - ``CLOS:MAP-DEPENDENTS` (`CLOS:FUNCALLABLE-STANDARD-CLASS` `T`)`
`(`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:

  - ``CLOS:ADD-DEPENDENT` (`STANDARD-GENERIC-FUNCTION` `T`)`
  - ``CLOS:MAP-DEPENDENTS` (`STANDARD-GENERIC-FUNCTION` `T`)`

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 or generic function metaobject.
  `function`
    a function which accepts one argument.
Values
  The values returned by this generic function is 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:ADD-DEPENDENT` (`STANDARD-CLASS` `T`)`
  - ``CLOS:REMOVE-DEPENDENT` (`STANDARD-CLASS` `T`)`
`(`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:ADD-DEPENDENT` (`CLOS:FUNCALLABLE-STANDARD-CLASS` `T`)`
  - ``CLOS:REMOVE-DEPENDENT` (`CLOS:FUNCALLABLE-STANDARD-CLASS` `T`)`
`(`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:

  - ``CLOS:ADD-DEPENDENT` (`STANDARD-GENERIC-FUNCTION` `T`)`
  - ``CLOS:REMOVE-DEPENDENT` (`STANDARD-GENERIC-FUNCTION` `T`)`

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

| These notes document CLISP version 2.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
29.10. Slot Access | Home | 29.12. Deviations from AMOP