DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

(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