Common Lisp Несколько метаклассов
Недавно обнаружив активный форк веблоков, я хотел бы объединить его с библиотекой ORM mito.
Weblocks определяет макрос defwidget
который на практике оборачивает defclass
вот так:
(defclass my-class ()
((slot))
(:metaclass weblocks/widgets/mop:widgets-class))
Между тем Мито работает так:
(defclass my-class ()
((...))
(:metaclass mito:dao-table-class))
Как я могу сделать так, чтобы следующее работало?
(defclass my-class ()
(...))
(defvar *obj* (make-instance 'my-class))
(render *obj*) ;render from weblocks
(save-dao *obj*) ;save-dao from mito
(my-method *obj*)
Я пробовал наследование, но потерпел неудачу разными способами. Я только использовал CLOS короткое время. Таким образом, у меня есть проблемы с измерением, где на спектре
"Я тупой <=====> Это невозможно"
Я стою. Любая помощь будет оценена.
2 ответа
Я пробовал наследование, но потерпел неудачу разными способами. Я только использовал CLOS короткое время. Таким образом, у меня есть проблемы с измерением, где на спектре...
Не волнуйтесь, прыгнуть прямо к метаобъектам с небольшим опытом работы с CLOS, безусловно, сложно, я рекомендую прочитать "Искусство протокола метаобъекта" (также известного как "AMOP" Грегора Кикзалеса и Джима Дес Ривьера). Роберт Странд (Robert Strandh) представляет HTML-версию глав 5 и 6 по адресу http://metamodular.com/CLOS-MOP.
Вы хотите определить гибридный метакласс, который наследуется от обоих метаклассов.
(defclass hybrid-metaclass (mito:dao-table-class
weblocks:widget-class)
())
Если вы определите класс с помощью вышеуказанного метакласса, вы получите это предупреждение:
;; WARNING: #<HYBRID-METACLASS COMMON-LISP-USER::MY-WIDGET {100B8FE683}> is not
;; defined to be a subclass of WEBLOCKS:WIDGET; consider adding WEBLOCKS:WIDGET
;; or a subclass thereof to the superclass list
widget-class
метакласс ожидает, что все его классы наследуются от базового класса, weblocks:widget
,
Давайте определим такой базовый объект для нашего гибридного метакласса:
(defclass hybrid-widget (weblocks:widget) ()
(:metaclass hybrid-metaclass))
Вот, hybrid-widget
наследует от weblocks:widget
и имеет метакласс hybrid-metaclass
, Все ваши виджеты должны наследоваться от этого класса и иметь метакласс hybrid-metaclass
(не стесняйтесь, чтобы найти лучшее имя).
Даже если это можно решить, как подсказывает @coredump, я не рекомендую смешивать модель (хранилище и бизнес-логику) и виджет (представление этих объектов) в одном классе.
Обычно я определяю свой виджет со слотом, указывающим на объект. Таким образом, вы также можете определить виджеты, которые содержат списки объектов. Это полезно, когда создание виджета для каждого отдельного объекта не имеет смысла.
Вам нужно сделать ссылку 1-1 между объектом и виджетом, когда вам нужно обновить представление объекта отдельно от других блоков в ответ на какое-то действие, например, при пометке задачи как DONE.