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

7.6 メタオブジェクトプロトコル

CLOS 風のオブジェクトシステムでは、オブジェクトシステムがそれ自身の上に 構築されます。すなわち、クラス構造のようなもの、クラスをどのように 生成するか、インスタンスをどのように生成し初期化するか、メソッドをどのように ディスパッチし呼び出すか、これらはすべてオブジェクトシステムによって、 定義されます。たとえば、クラスはジェネリックな構造と標準的クラスの 振舞いを定義する <class> クラスのインスタンスです。<class> をサブクラス化すると、デフォルトのものとは違う振舞いをする、独自の クラス集合をつくることができます。これは結局、独自のオブジェクトシステムを つくることになります。

メタオブジェクトプロトコルは、どのようにオブジェクトシステムを 構築するかに関連する API 群の定義です。ブロック構築のクラス、オブジェクト システムを操作するあいだに呼ばれるジェネリック関数の名前と順序などです。 これらのクラスをサブクラス化し、これらのメソッドを特定化することは、 オブジェクトシステムの振舞いをカスタマイズすることを意味します。


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

7.6.1 クラスのインスタンシエーション

すべてのクラスはある特殊なクラスのグループのインスタンスになっています。 他のクラスのクラスになれるようなクラスのことを メタクラス と呼びます。 Gauche では <class> クラスおよびそのサブクラスのみがメタクラスに なれます。

define-class の展開

define-class マクロは基本的には <class> (あるいは指定された メタクラス)のインスタンスを生成するコードのラッパーで、それを与えられた 名前に束縛します。以下のような define-class 形式を前提とします。

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

これを次のように展開します。 (‘`gauche-config --syslibdir`/gauche/object.scm’ の define-class マクロの定義をみれば展開形式を見ることができます。)

 
(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))

生成されるクラスのクラス、つまり、metaclass は以下のルールで 決定されます。

  1. もし、:metaclass オプションが define-class マクロに 与えられていれば、その値を使います。その値は、<class> クラスか あるいはその子孫でなければなりません。
  2. さもなければ、クラス順位リスト中のクラスのメタクラスが試されます。

クラスの名前、スーパークラス、スロットの定義は初期化引数として ジェネリック関数 make に引き渡され、それ以外の引数は define-class に引き渡されます。初期化引数 define-modules は どのモジュールでそのクラスが定義されたかを覚えておくために引き渡されます。 これはこのクラスの再定義のとき用です。

スロットの仕様 slot-specs は内部メソッド process-slot-definitions (これは直接呼び出すことはできません)で処理され、スロット定義になります。 厳密には、:init-form スロットオプションは、:init-thunk オプション になり、:getter:setter:accessor のスロットオプションは 引用されます。

クラス(metaclass のインスタンス)が生成された後、name のグローバル な束縛がチェックされます。それが、クラスに束縛されていれば、クラスの再定義 プロトコルが起動されます(クラスの再定義 参照)。

その後、slot-specs 中で、:getter:setter:accessor スロットオプションに与えられたメソッドが集められ、対応する ジェネリック関数に登録されます。

クラス構造

Class: <class>

すべてのメタクラスのベースクラスである <class> は以下のような スロットを持っています。これらのスロットは内部的な管理のためにあるので クラスが初期化された後に、これらの値を変更すべきではないということに 注意してください。クラスの情報を得るには、これらのスロットに直接 アクセスするのではなく、クラスオブジェクト にある手続きを使うことをおすすめ します。

Instance Variable of <class>: name

クラスの名前、define-class マクロに与えられたシンボルです。 class-name はこの値を返します。

Instance Variable of <class>: cpl

クラス順位リストです。class-precedence-list はこの値を返します。

Instance Variable of <class>: direct-supers

直接スーパークラスのリストです。 class-direct-supers はこの値を返します。

Instance Variable of <class>: accessors

スロットアクセサの連想リストです。これは各スロットがどのようにアクセスされる べきかをカプセル化しています。

Instance Variable of <class>: slots

スロット定義のリストです。class-slots はこの値を返します。 スロット定義についての詳細は、スロット定義オブジェクト を参照してください。

Instance Variable of <class>: direct-slots

このクラスの定義で直接指定された(つまり継承したものではない)スロット定義の リストです。class-direct-slots はこの値を返します。

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

インスタンスにアロケートされるスロットの数です。

Instance Variable of <class>: direct-subclasses

このクラスを直接継承しているクラスのリストです。 class-direct-subclasses はこの値を返します。

Instance Variable of <class>: direct-methods

このクラスを特定化子リスト中にもつメソッドのリストです。 class-direct-methods はこの値を返します。

Instance Variable of <class>: initargs

このクラスが生成されるときの初期化引数リストです。この情報は 再定義されたクラスを初期化するのに使います(クラスの再定義 参照)。

Instance Variable of <class>: defined-modules

このクラスがグローバル束縛をもつモジュールのリストです。

Instance Variable of <class>: redefined

このクラスが再定義された場合、このスロットは新しいクラスへの参照を含みます。 そうでない場合にはこのスロットは #f をもっています。

Instance Variable of <class>: category

このスロットの値は、このクラスがどのように生成されたかを示しています。 Scheme 定義のクラスは、scheme というシンボルを持っています。それ以外の 値は内部的に使用するだけです。

<class> 用の make メソッド

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

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

7.6.2 スロットアクセスのカスタマイズ

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: make (class <method>) &rest initargs

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

7.6.4 メソッド適用のカスタマイズ

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 November, 22 2009 using texi2html 1.78.