Множественные метаклассы Common Lisp

Недавно обнаружив активный форк веб-блоков, я хотел бы объединить его с библиотекой ORM mito.

Weblocks определяет макрос defwidget, который на практике обертывает defclass следующим образом:

(defclass my-class ()
  ((slot))
  (:metaclass weblocks/widgets/mop:widgets-class))

Между тем Mito работает так:

(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 совсем недавно. Таким образом, мне трудно определить, где в спектре

«Я тупой‹ =====> Это невозможно »

Я стою. Любая помощь будет оценена по достоинству.


person otyn    schedule 09.12.2018    source источник
comment
Хороший вопрос. Я открыл связанную проблему с Weblocks: github.com/40ants/weblocks/issues/19 Покажи нам свой прогресс по проблеме веб-блокировки, gitter или reddit, когда сможешь!   -  person Ehvince    schedule 17.12.2018


Ответы (2)


Я пробовал наследование, но не удалось по-разному. Я использовал CLOS совсем недавно. Таким образом, у меня проблемы с определением того, где находится спектр ...

Не волнуйтесь, сразу перейти к метаобъектам с небольшим опытом работы с CLOS, конечно, сложно. Я рекомендую прочитать «Искусство протокола метаобъектов» (также известное как «AMOP» Грегора Кичалеса и Джима Дес Ривьера). 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 (не стесняйтесь найти лучшее имя).

person coredump    schedule 09.12.2018
comment
Решения кажутся отличными, ваша помощь очень ценится. - person otyn; 10.12.2018
comment
Я не хотел сразу углубляться в глубокую часть пула (= метаклассы), но использование этих библиотек позволило бы мне работать над этим на работе, то есть быстрее изучать CLOS. Кроме того, я нигде не видел, чтобы проблема нескольких метаклассов решалась напрямую. - person otyn; 10.12.2018

Даже если это возможно решить, как предлагает @coredump, я не рекомендую вам смешивать модель (хранилище и бизнес-логику) и виджет (представление этих объектов) в одном классе.

Обычно я определяю свой виджет слотом, указывающим на объект. Таким образом, вы также можете определить виджеты, которые содержат списки объектов. Это полезно, когда делать виджет для каждого отдельного объекта не имеет смысла.

Вам нужно только создать связь 1-1 между объектом и виджетом, когда вам нужно обновить представление объекта отдельно от других блоков в качестве ответа на какое-либо действие, например, при пометке задачи как выполненной.

person Alexander Artemenko    schedule 12.12.2018
comment
Спасибо за ваш вклад. Я пробую разные подходы к этому, и в моем игрушечном приложении для тестирования есть эта ссылка 1-1. Можно ли добавить минимальный пример вашего подхода к руководству по реблокам? - person otyn; 17.12.2018