Next: 15.5 メソッドの探索
Up: 15 CLOSのクラスシステムの実現
Previous: 15.3 メソッドの実現
インスタンスの生成というのは,クロージャの生成になります.
関数instanceは以下のように,クラス名と初期メッセージ(args)を
与えると(self x &rest args)という引数を受けとるクロージャを
返します.
クロージャに保存される局所変数は,
(cls-local-variables (get-class class-name))
です.つまり,クラスに宣言されているインスタンス変数のリストが
クロージャ定義のlet文の局所変数宣言のところに渡されます.
(defun make-instance* (cls-name)
(let ((class (get-class cls-name)))
(create-instance cls-name
(cls-local-variables class)
(cls-accessors class))))
(defun create-instance
(cls-name vars&values vars&accessors)
(eval `(internal-create-instance
,cls-name
,vars&values ,vars&accessors)))
;;;
;;; Including instance-variable accessor version
;;;
(defmacro internal-create-instance
(cls-name vars&values vars&accessors)
(let ((lambda-parameter (gensym)))
`(let ,(cons '(var-store (make-hash-table))
vars&values)
(setf (gethash 'class var-store)
#'(lambda () ',cls-name))
,@(mapcar
#'(lambda (var&accessor)
`(setf (gethash ',(cadr var&accessor)
var-store)
#'(lambda () ,(car var&accessor))) )
vars&accessors)
,@(mapcar
#'(lambda (var&accessor)
`(setf (gethash ',(caddr var&accessor)
var-store)
#'(lambda (,lambda-parameter)
(setf ,(car var&accessor)
,lambda-parameter))) )
vars&accessors)
#'(lambda (self x &rest args)
(let
((local-var-function (gethash x var-store)))
(if local-var-function
(apply local-var-function args)
(let ((method (find-method* x ',cls-name)))
(if method
(apply method (cons self args))
(error
"~a undefined method for class ~a"
x ',cls-name)))))))))
クロージャは,送られてくるメソッドがクラス(class-name)に
登録されているかどうか探しだし(find-method),そのメソッドが
あればそれを実行する,というように作ります.
make-instance*はスロットの初期化引数などはとれない形になって
います.
generated through LaTeX2HTML. M.Inaba 平成18年5月6日