в Common-Lisp CLOS
Можно ли динамически добавить еще один суперкласс
в существующем классе.
Обновление:
Я хотел определить 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 группа)) вызывается
здесь следует вызвать соответствующее задание к группе
(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))
...)
(если он есть, я могу проверить, есть он или нет)
Но я хочу, чтобы он работал для любого объекта, независимо от того, есть ли у него метод перезаписи или нет
Так что, в принципе, необходимо изменить код для любой вещи в этих классах и методах.
Итак, я решил, что нужно динамически добавить родительский класс, чтобы определить для него этот метод.
Другой способ может быть defadvide или fwrapper , но его нет в SBCL.