Common-Lisp CLOS で
既存のクラスにもう 1 つのスーパー クラスを動的に追加することは可能ですか。
アップデート:
同じ引数を使用してメソッド/関数にいくつかの動作を関連付けるdefassocのようなマクロを定義したかった
例えば
(defassoc (gname (s (g group)))
((name1 (name ((corresponding-task task g) s)))
(record1 (record ((corresponding-task task g) s))))
(let ((n name1)
(r record1))
(if (and name1 record1)
(display name1 record1)
(call-next-method))))
に展開
(symbol-macrolet ((name1 (name ((corresponding-task task g) s)))
(record1 (record ((corresponding-task task g) s))))
(defmethod gname :after (s (g group))
(let ((n name1) (r record1))
(if (and name1 record1)
(display name1 record1)
(call-next-method)))))
ここでは、 (gname (s (g group)) が呼び出されたときに、対応するタスクをグループに呼び出す必要があることを確認しています
(name ((corresponding-task task g) s)
(record ((corresponding-task task g) s)
このマクロを使用しました
(defmacro defassoc ((main-method main-method-lambda-list)
funspec-list &body body)
`(symbol-macrolet ,(mapcar (lambda (fspec)
(destructuring-bind (name f) fspec
(list name f)))
funspec-list)
(defmethod
,main-method ,mod ,main-method-lambda-list
,@(if body
body
`(if (and
,@(mapcar (lambda (e)
(car e))
funspec-list))
(call-next-method)))))
しかし、問題はそれが上書きされることです
(defmethod gname :after (s (g group))
...)
(ある場合は、あるかどうかを確認できます。)
しかし、上書きするメソッドがあるかどうかに関係なく、どのオブジェクトでも機能するようにしたい
したがって、基本的に、そのクラスとメソッドのコードを変更する必要があります。
したがって、親クラスを動的に追加してこのメソッドを定義することを決定した方法の1つです。
別の方法としてdefadvideまたはfwrapperを使用できますが、SBCLにはありません。