Subsections

オブジェクト指向プログラミング

オブジェクトの構造と動作は、クラスの中に記述されている。 それらは、defclassマクロやdefmethod特殊書式により定義されている。 defclassは、クラスの名前・そのスーパークラス・スロット変数名とオプションとして 任意の型およびメッセージの前方への送信を定義する。 defmethodは、メッセージが送られてきたとき呼び出される メソッドを定義する。 クラス定義は、symbolの特殊値として割り当てられる。 クラスは、Common Lispのsutructureのcounter部分と考えることができる。 スロットアクセス関数とsetfメソッドは、defclassによってそれぞれの スロットに自動的に定義される。

大部分のクラスは、内部クラスmetaclassから派生している。 metaclassのサブクラスであるクラスvector-class はベクトルのためのメタクラスである。 もし、class-variablesやclass-methodsを使いたいときは、 metaclassのサブクラスとして自分独自のメタクラスを作り、 メタクラスの名前を:metaclassのキーワードでdefclassに与えればよい。

ベクトルは、その他のrecord-likeオブジェクトと違っている。 なぜなら、ベクトルのインスタンスは、任意の数の要素を持っているが、 record-likeオブジェクトは固定数のスロットを持っている。 EusLispのオブジェクトは、record-likeオブジェクトかまたはベクトルであって、 両方同時ではない。

要素の型が決められているかまたは要素が入れられないベクトルも defclassによって定義することができる。 次の例の中で、クラスintvec5は5つのinteger要素を持つクラス として定義されている。 自動型判定と型変換は、要素がインタープリタによってアクセスされたとき 実施される。 正しい宣言でコンパイルされたとき、高速なアクセスコードが生成される。

(defclass intvec5 :super vector :element-type :integer :size 5)
(setq x (instantiate intvec5))  --> #i(0 0 0 0 0)

メッセージがオブジェクトに送られたとき、 一致するメッセージを最初そのオブジェクトのクラスから探し、次にそのスーパークラスから探して、 スーパークラスが尽きるまで探す。 もし、メソッドが定義されてなかったならば、 前方のリストが探される。 この前方探索は、疑似多重継承によって作られる。 もし、探索が失敗したときは、:nomethodというメソッド名が探され、 メソッドは、全ての引数のリストと一緒に呼び出される。 次の例の中で、メッセージ:telephone:mailperson という型のオブジェクトスロットsecretaryに送られる。 そして、メッセージgo-homeはスロットchauffeurに送られる。

(defclass president :super object
                    :slots ((name :type string)
                            (age  :type :integer)
                            (secretary  :type person
                                        :forward (:telephone :mail))
                            (chauffeur  :forward (:go-home))))

メソッドにおいて、2つのローカル変数(classself) が使用可能となる。 これらの変数は変更すべきでない。 もし、変更したならば、システムから供給された変数は隠され、 send-supersend selfは正しい動作をしない。

クラスとメソッド




defclass   [マクロ] 

classname &key (super object)
slots
; (var &optional type &rest forward selectors)*
(metaclass metaclass)
(element-type t)
(size -1)
クラスを生成または再定義する。 異なったスーパークラスやスロットを持つクラスに再定義したとき、 メソッドが新しいスロット配置を仮定するため、 以前のクラスを継承する古いオブジェクトは予想できない振舞いをする。


defmethod classname &rest (selector lambda-list &rest body) [特殊]

classnameの1つ以上のメソッドを定義する。 それぞれのselectorは、キーワードsymbolでなければならない。


defclassmethod classname &rest (selector lambda-list &rest body) [マクロ]



classp object [関数]

objectがクラスオブジェクトのときTを返す。 そのオブジェクトは、クラスmetaclassかそのサブクラスの インスタンスである。


subclassp class super [関数]

classsuperのサブクラスであることを検査する。


vector-class-p x [関数]

xが、vector-classのインスタンスであるとき、Tを返す。


delete-method class method-name [関数]

method-nameのメソッド定義をclassから除く。


find-method object selector [関数]

selectorに記述されたメソッドをobjectのクラスおよび そのスーパークラスの中から見つける。 objectが、selectorに応じることができるかどうかを 知るために使用される。


class-hierarchy class [関数]

classの下の継承構造を表示する。


system:list-all-classes [関数]

今まで定義されたクラスを全てリストアップする。


system::method-cache &optional flag [関数]

メソッドキャッシュのヒット率を調査し、 ヒットとミスの2つの数値のリストを返す。 もしflagがNILのとき、メソッドキャッシュは無効になる。 もしnon-NILのflagが与えられたとき、メソッドキャッシュは初期化され キャッシュ可能になる。


メッセージ送信



send object selector &rest args [関数]

objectselectorargで構成されるメッセージを送信する。 objectは、何でもよいが数値はいけない。 selectorはキーワードとして評価されなければならない。


send-message target search selector &rest args [関数]

send-superを実行するための低レベル命令である。


send* object selector &rest msg-list [マクロ]

send*は、引数のリストにsend-messageを適用する。 sendsend*の関係は、 funcallapplyあるいはlistlist*の関係に似ている。


send-all receivers selector &rest mesg [関数]

全てのreceiversに同じメッセージを送信し、結果をリストとして集める。


send-super selector &rest msgs [マクロ]

msgsselfに送信するが、 メソッドが定義されているクラスのスーパークラスでの メソッドを探し始める。 メソッドの外のsend-superは、エラーとなる(すなわち、メソッド内で なければならない)。


send-super* selector &rest msg-list [マクロ]

send-super*は、send-superのapply版である。


インスタンス管理



instantiate class &optional size [関数]

classから新しいオブジェクトを作る低レベル命令である。 もしclassvector-classならば、sizeがなければならない。


instance class &rest message [マクロ]

インスタンスが作られ、そこにmessageが送られる。


make-instance class &rest var-val-pairs [関数]

classのインスタンスを作成し、スロット変数を var-val-pairsのように設定する。 例えば、(make-instance cons :car 1 :cdr 2) は、(cons 1 2)と同等である。


copy-object object [関数]

copy-object関数は、参照トポロジー(再帰参照でも構わない)を保ったまま コピーするために使用する。 copy-objectは、独自性の保存に触れないsymbolやパッケージを除いて、 objectからアクセス可能などんなオブジェクトもコピーする。 copy-objectは、オブジェクトの中の全ての参照を2度妨害する。 1度が、新しいオブジェクトを作り既にコピーされたオブジェクトのオリジナルに マークを付けるとき、そしてマークを消すときにもう1度。 この2段階の処理は、copy-objectcopy-seqよりも遅くする。 もし順番にコピーをしたいならば、 copy-seqcopy-treeを使用することを薦める。


become object class [関数]

objectのクラスをclassに変更する。 古いクラスと新しいクラス両方のスロット構造は、一致しなければならない。 普通、2要素ベクトル間のクラス変更にのみ安全に使用することができる。 例えば、整数ベクトルからビットベクトルへの変更。


replace-object dest src [関数]

destは、srcのサブクラスのインスタンスでなければならない。


class object [関数]

objectのクラスオブジェクトを返す。 クラス名を得るために、クラスオブジェクトに:nameメッセージを送る。


derivedp object class [関数]

derivedpは、objectclassまたはそのサブクラスから インスタンス化されているかどうかを判定する。 subclasspderivedp関数は、クラス継承のなかを探索できない。 したがって、一定時間内に型のチェックがいつも終了する。


slot object class idex-or-name [関数]

スロット値の名前かインデックスを返す。


setslot object class index-or-name value [関数]

setslotは、内部処理関数でユーザーが使用できない。 代りに、setfslotの組み合せを使用する。


基本クラス




object [クラス]


  :super    

:slots


objectは、最も基本のクラスである。それは、クラス継承の最上位に位置する。 スロット変数が定義されていないため、objectはインスタンスを作るために 使用しない。


:prin1 &optional stream &rest mesg [メソッド]

標準の再読み込可能なオブジェクトフォーマットのなかにあるオブジェクトを 表示する。 そのクラス名とアドレスは、角括弧でくくられ、符号を前に置く。 どのオブジェクトのサブクラスもmesg文字列で説明するマクロsend-super を使ってもっと広範囲な情報と一緒にそれ自身を印刷するのにこの方法を 使用することができる。 オブジェクトは、もし#$ <$で始まるなら、再読み込み可能である。 そのクラス名・正確なアドレス・どのLispでも読み込可能な情報・>をあとに 従えて。 全てのデータオブジェクトは数値を除いて、objectを継承している。 この構文で書式の表示が得られる。(symbolや文字列でも構わない) この構文で述べることは、symbolにsetqし忘れたデータオブジェクトを 把握することができる。 ただし、表示された後にガーベージコレクションが起こらない限りである。


:slots [メソッド]

変数名のリストおよびオブジェクトの全てのスロットと対になる値を返す。 このリストにassocを適用することにより、スロットの詳細値が得られる。 しかしながら、それらを変更することはできない。


:methods &optional subname [メソッド]

このオブジェクトから呼べる全てのメソッドのリストを返す。 subnameを指定すると、メソッド名のなかにそれを含むメソッドのみ返す。


:get-val variable-name [メソッド]

variable-nameに該当するスロットの値を返す。 スロットが存在しない時、エラーを報告する。


:set-val variable-name value [メソッド]

variable-nameに該当するスロットにvalueを代入する。 スロットが存在しない時、エラーを報告する。



propertied-object [クラス]


  :super   object 

:slots plist


property-listを持つオブジェクトを定義する。 他のCommon Lispと違って、 EusLispは、たとえ、symbolでなかったとしても、property-listを持つ propertied-objectを継承するどんなオブジェクトも 許可する。


:plist &optional plist [メソッド]

もしplistが明記されるならば、このオブジェクトのplistスロットに 設定する。そのため、以前のplistの値はなくなる。 plistは、 ((indicator1 . value1) (indicator2 . value2) ...)の書式にすべきである。 それぞれのindicatorは、eq関数で等価性をテストされたどのような lisp書式も可能である。 symbolがindicatorとして用いられたとき、内部パッケージを広く実行される 等価性のチェックを確実にするためにキーワードの使用を推薦する。 :plistは、主なplistを返す。


:get indicator [メソッド]

plistのなかでindicatorと結び付く値を返す。 (send x :get :y) == (cdr (assoc :y (send x :plist)))


:put indicator value [メソッド]

plistのなかで、valueindicatorを結び付ける。


:remprop indicator [メソッド]

plistからindicatorとvalueの組を削除する。 さらに、:getを試すとvalueとしてNILを返す。


:name &optional name [メソッド]

plistのなかの:name特性を定義し、取り出す。 この特性は、表示のために使用される。


:prin1 &optional stream &rest mesg [メソッド]

再読み込み可能な書式のオブジェクトを表示する。 もしオブジェクトが:name特性を持っているならば、 オブジェクトのアドレスの後に特性を表示する。



metaclass [クラス]


  :super   propertied-object 

:slots name super cix vars types forwards methods


metaclassは、複数クラスを定義する。独自のクラス変数を持つ複数クラスは、 それらのスーパークラスとしてmetaclassを定義しなければならない。


:new [メソッド]

このクラスのインスタンスを生成し、全てのスロットをNILにした後、 それを返す。


:super [メソッド]

このクラスのスーパークラスオブジェクトを返す。 一旦クラス定義したスーパークラスを変更することはできない。


:methods [メソッド]

このクラスで定義された全てのメソッドのリストを返す。 そのリストは、メソッド名とパラメータと本体を組みにしたリスト によって構成されたリストである。


:method name [メソッド]

nameで関連づけられたメソッド定義を返す。 もし見つからなければ、NILを返す。


:method-names subname [メソッド]

メソッド名のなかにsubnameを含む全てのメソッド名のリストを返す。 メソッドは、このクラスのなかのみ探索される。


:all-methods [メソッド]

このクラスとその全てのスーパークラスのなかで定義されているすべてのメソッドの リストを返す。 言い替えると、このクラスのインスタンスは、これらのメソッドを 実行することができる。


:all-method-names subname [メソッド]

subnameと一致する全てのメソッド名のリストを返す。 その探索は、このクラスからobjectまで実行される。


:slots [メソッド]

スロット名のベクトルを返す。


:name [メソッド]

このクラスのsymbol名を返す。


:cid [メソッド]

このクラスと同一であることを示すために、このクラスのインスタンスすべてに 割り当てられた整数を返す。 これは、システム内部のクラステーブルへのインデックスで、 このクラスの下に新しいサブクラスが定義されたとき、変更される。


:subclasses [メソッド]

このクラスの直接のサブクラスのリストを返す。


:hierarchy [メソッド]

このクラスの下に定義された全てのサブクラスのリストを返す。 全てのクラス継承の広範囲なリストを得るためには、class-hierarchy関数 を呼び出す。


find-method object selector [関数]

objectのクラスやそのスーパークラスのなかで、selectorと一致する メソッドを探索する。 この関数は、objectのクラスが不確かで、そのobjectが エラーなしにメッセージを受け取ってくれるかどうかを知りたい時に役立つ。


This document was generated using the LaTeX2HTML translator on Sat Feb 5 14:36:44 JST 2022 from EusLisp version 138fb6ee Merge pull request #482 from k-okada/apply_dfsg_patch