[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6 Metaobject protocol

In CLOS-like object systems, the object system is built on top of itself—that is, things such as the structure of the class, how a class is created, how an instance is created and initialized, and how a method is dispatched and called, are all defined in terms of the object system. For example, a class is just an instance of the class <class> that defines a generic structure and behavior of standard classes. If you subclass <class>, then you can create your own set of classes that behaves differently than the default behavior; in effect, you are creating your own object system.

Metaobject protocols are the definitions of APIs concerning about how the object systems are built—building-block classes, and the names and orders of generic functions to be called during operations of the object system. Subclassing these classes and specializing these methods are the means of customizing object system behaviors.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6.1 Class instantiation

Every class is an instance of a group of special classes. A class that can be a class of another class is called metaclass. In Gauche, only the <class> class or its subclasses can be a metaclass.

Expansion of define-class

The define-class macro is basically a wrapper of the code that creates an instance of <class> (or specified metaclass) and bind it to the given name. Suppose you have the following define-class form.

 
(define-class name (supers)
  slot-specs
  options …)

It is expanded into a form like this (you can see the exact form by looking at the definition of define-class macro in ‘`gauche-config --syslibdir`/gauche/object.scm’).

 
(define name
  (let ((tmp1 (make metaclass 
                 :name 'name :supers (list supers)
                 :slots (map process-slot-definitions
                             slot-specs)
                 :defined-modules (list (current-module))
                 options …)))
    … check class redefinition …
    … registering accessor methods …
    tmp1))

The created class's class, i.e. metaclass, is determined by the following rules.

  1. If :metaclass option is given to the define-class macro, its value is used. The value must be the <class> class or its descendants.
  2. Otherwise, the metaclasses of the classes in the class precedence list is examined.

The class's name, superclasses, and slot definitions are passed as the initialization arguments to the make generic function, with other arguments passed to define-class. The initialization argument defined-modules is passed to remember which module the class is defined, for the redefinition of this class.

The slot specifications slot-specs are processed by internal method process-slot-definitions (which can't be directly called) to be turned into slot definitions. Specifically, an :init-form slot option is turned into an :init-thunk option, and :getter, :setter and :accessor slot options are quoted.

After the class (an instance of metaclass) is created, the global binding of name is checked. If it is bound to a class, then the class redefinition protocol is invoked (see Class redefinition).

Then, the methods given to :getter, :setter and :accessor slot options in slot-spec are collected and registered to the corresponding generic functions.

Class structure

Class: <class>

The base class of all metaclasses, <class>, has the following slots. Note that these slots are for internal management, and users shouldn't change their values after the class is initialized. It is recommended to obtain information about a class by procedures described in Class object, instead of directly accessing those slots.

Instance Variable of <class>: name

The name of the class; the symbol given to define-class macro. class-name returns this value.

Instance Variable of <class>: cpl

Class precedence list. class-precedence-list returns this value.

Instance Variable of <class>: direct-supers

The list of direct superclasses. class-direct-supers returns this value.

Instance Variable of <class>: accessors

An assoc list of slot accessors—it encapsulates how each slot should be accessed.

Instance Variable of <class>: slots

A list of slot definitions. class-slots returns this value. See Slot definition object, for the details of slot definitions.

Instance Variable of <class>: direct-slots

A list of slot definitions that is directly specified in this class definition (i.e. not inherited). class-direct-slots returns this value.

Instance Variable of <class>: num-instance-slots

The number of instance allocated slots.

Instance Variable of <class>: direct-subclasses

A list of classes that directly inherits this class. class-direct-subclasses returns this value.

Instance Variable of <class>: direct-methods

A list of methods that has this class in its specializer list. class-direct-methods returns this value.

Instance Variable of <class>: initargs

The initialization argument list when this class is created. The information is used to initialize redefined class (see Class redefinition).

Instance Variable of <class>: defined-modules

A list of modules where this class has a global binding.

Instance Variable of <class>: redefined

If this class has been redefined, this slot contains a reference to the new class. Otherwise, this slot has #f.

Instance Variable of <class>: category

The value of this slot indicates how this class is created. Scheme defined class has a symbol scheme. Other values are for internal use.

The make method for <class>

Method: make (class <class>) &rest initargs

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6.2 Customizing slot access

Generic Function: compute-slots
Generic Function: compute-get-n-set
Function: slot-ref-using-accessor obj slot-accessor
Function: slot-set-using-accessor obj slot-accessor value

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6.3 Method instantiation

Method: make (class <method>) &rest initargs

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6.4 Customizing method application

Generic Function: apply-generic gf args
Generic Function: sort-applicable-methods gf methods args
Generic Function: method-more-specific? method1 method2 classes
Generic Function: apply-methods gf methods args
Generic Function: apply-method gf method build-next args

[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated by Shiro Kawai on October, 7 2008 using texi2html 1.78.