2008/01/10

Common Lisp : funcallable-standard-class

Common Lisp の MOP の世界に funcallable-standard-class というものがあります。
その名のとおり関数として呼び出すことのできるオブジェクトを作るメタクラスです。
:metaclass で funcallable-standard-class を指定します。
set-funcallable-instance-function で実行する関数を指定します。
関数としての呼び出しは funcall と apply が使用可能ですが、(setf symbol-function) で任意のシンボルの関数にしてしまうこともできます。

(use-package :sb-mop)

(defclass adder ()
((n :initarg :n :initform 1))
(:metaclass funcallable-standard-class))

(defmethod initialize-instance :after ((adder adder) &rest args)
(declare (ignore args))
(set-funcallable-instance-function
adder
#'(lambda (n)
(+ n (slot-value adder 'n)))))

(defun add (n)
n)

(defparameter adder (make-instance 'adder))

(setf (symbol-function 'add) adder)

(add 1) ; => 2
(funcall adder 1) ; => 2
(setf (slot-value adder 'n) 10)
(add 1) ; => 11
(apply adder (list 1)) ; => 11

これを使えば (with-ole-object (ie "InternetExplorer.Application") (ie :visible t) (ie :navigate "http://...") なんてことができるかなと思ったのですが、(setf symbol-function) は影響がグローバルなので使うのがためらわれます。

0 件のコメント: