Можно ли динамически добавить еще один суперкласс в существующий класс? - PullRequest
3 голосов
/ 15 августа 2011

в 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.

1 Ответ

3 голосов
/ 15 августа 2011

Да, это возможно.Самый простой способ - просто переопределить класс.Вы делаете это, выполняя очередной вызов DEFCLASS.Если вы хотите делать более сложные вещи, вы должны прибегнуть к MOP (MetaObject Protocol).По сути, все, что вы когда-либо хотели бы сделать, возможно с помощью MOP, но мне потребуется более подробная информация о том, что вы пытаетесь сделать, чтобы объяснить это дальше.

...