DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH
 

(goops.info.gz) Customizing Class Definition

Info Catalog (goops.info.gz) Class Definition Internals (goops.info.gz) Defining New Classes (goops.info.gz) STKlos Compatibility
 
 Customizing Class Definition
 ----------------------------
 
 During the initialization of a new class, GOOPS calls a number of
 generic functions with the newly allocated class instance as the first
 argument.  Specifically, GOOPS calls the generic function
 
    * (initialize CLASS ...)
 
 where CLASS is the newly allocated class instance, and the default
 `initialize' method for arguments of type `<class>' calls the generic
 functions
 
    * (compute-cpl CLASS)
 
    * (compute-slots CLASS)
 
    * (compute-get-n-set CLASS SLOT-DEF), for each of the slot
      definitions returned by `compute-slots'
 
    * (compute-getter-method CLASS SLOT-DEF), for each of the slot
      definitions returned by `compute-slots' that includes a `#:getter'
      or `#:accessor' slot option
 
    * (compute-setter-method CLASS SLOT-DEF), for each of the slot
      definitions returned by `compute-slots' that includes a `#:setter'
      or `#:accessor' slot option.
 
 If the metaclass of the new class is something more specialized than the
 default `<class>', then the type of CLASS in the calls above is more
 specialized than `<class>', and hence it becomes possible to define
 generic function methods, specialized for the new class's metaclass,
 that can modify or override the default behaviour of `initialize',
 `compute-cpl' or `compute-get-n-set'.
 
 `compute-cpl' computes the class precedence list ("CPL") for the new
 class ( Class precedence list), and returns it as a list of
 class objects.  The CPL is important because it defines a superclass
 ordering that is used, when a generic function is invoked upon an
 instance of the class, to decide which of the available generic function
 methods is the most specific.  Hence `compute-cpl' could be customized
 in order to modify the CPL ordering algorithm for all classes with a
 special metaclass.
 
 The default CPL algorithm is encapsulated by the `compute-std-cpl'
 procedure, which is in turn called by the default `compute-cpl' method.
 
  - procedure: compute-std-cpl class
      Compute and return the class precedence list for CLASS according
      to the algorithm described in  Class precedence list.
 
 `compute-slots' computes and returns a list of all slot definitions for
 the new class.  By default, this list includes the direct slot
 definitions from the `define-class' form, plus the slot definitions
 that are inherited from the new class's superclasses.  The default
 `compute-slots' method uses the CPL computed by `compute-cpl' to
 calculate this union of slot definitions, with the rule that slots
 inherited from superclasses are shadowed by direct slots with the same
 name.  One possible reason for customizing `compute-slots' would be to
 implement an alternative resolution strategy for slot name conflicts.
 
 `compute-get-n-set' computes the low-level closures that will be used
 to get and set the value of a particular slot, and returns them in a
 list with two elements.
 
 The closures returned depend on how storage for that slot is allocated.
 The standard `compute-get-n-set' method, specialized for classes of
 type `<class>', handles the standard GOOPS values for the
 `#:allocation' slot option ( allocation Slot Options.).  By
 defining a new `compute-get-n-set' method for a more specialized
 metaclass, it is possible to support new types of slot allocation.
 
 Suppose you wanted to create a large number of instances of some class
 with a slot that should be shared between some but not all instances of
 that class - say every 10 instances should share the same slot storage.
 The following example shows how to implement and use a new type of slot
 allocation to do this.
 
      (define-class <batched-allocation-metaclass> (<class>))
      
      (let ((batch-allocation-count 0)
            (batch-get-n-set #f))
        (define-method (compute-get-n-set (class <batched-allocation-metaclass>) s)
          (case (slot-definition-allocation s)
            ((#:batched)
             ;; If we've already used the same slot storage for 10 instances,
             ;; reset variables.
             (if (= batch-allocation-count 10)
                 (begin
                   (set! batch-allocation-count 0)
                   (set! batch-get-n-set #f)))
             ;; If we don't have a current pair of get and set closures,
             ;; create one.  make-closure-variable returns a pair of closures
             ;; around a single Scheme variable - see goops.scm for details.
             (or batch-get-n-set
                 (set! batch-get-n-set (make-closure-variable)))
             ;; Increment the batch allocation count.
             (set! batch-allocation-count (+ batch-allocation-count 1))
             batch-get-n-set)
      
            ;; Call next-method to handle standard allocation types.
            (else (next-method)))))
      
      (define-class <class-using-batched-slot> ()
        ...
        (c #:allocation #:batched)
        ...
        #:metaclass <batched-allocation-metaclass>)
 
 The usage of `compute-getter-method' and `compute-setter-method' is
 described in  MOP Specification.
 
 `compute-cpl' and `compute-get-n-set' are called by the standard
 `initialize' method for classes whose metaclass is `<class>'.  But
 `initialize' itself can also be modified, by defining an `initialize'
 method specialized to the new class's metaclass.  Such a method could
 complete override the standard behaviour, by not calling
 `(next-method)' at all, but more typically it would perform additional
 class initialization steps before and/or after calling `(next-method)'
 for the standard behaviour.
 
Info Catalog (goops.info.gz) Class Definition Internals (goops.info.gz) Defining New Classes (goops.info.gz) STKlos Compatibility
automatically generated byinfo2html