Переходные классы в CLOS

Есть ли стандартный способ создать переходный класс в CLOS; то есть класс, который может быть собран после того, как все его экземпляры мертвы?

В SBCL я попробовал (setf test (defclass #:foo () ())), т.е. использовал неинтернированный символ, предполагая, что обычно это будет только имя класса, из-за которого класс сохраняется сборщиком мусора, но установка функции завершения SBCL для этого класса, а затем установка символа значение TEST в NIL показывает, что класс никогда не подвергается сборке мусора, независимо от того, сколько раз я запускаю (gc :full t). Что заставляет меня задуматься, возможно ли это, и если да, то как.


person Dolda2000    schedule 28.09.2012    source источник


Ответы (1)


Не имеет значения, что имя класса, символ, не интернировано в пакете. FIND-CLASS найдет класс, просматривая внутреннюю структуру данных реестра. Clozure Common Lisp использует, например, обычную хеш-таблицу CCL::%FIND-CLASSES%.

Стандартного способа нет. Стандарт Common Lisp не предоставляет никакого механизма. Обычно реализация CLOS хочет предоставить список всех подклассов определенного класса. Для этого ему нужна ссылка из класса на его подклассы. Не указано, что это должна быть слабая ссылка. Например, CLISP реализует его как слабую ссылку, а другие реализации Common Lisp — нет.

Эскиз решения:

  • Таким образом, в финализаторе вам понадобятся вызовы REMOVE-DIRECT-SUBCLASS (в каком пакете может быть эта функция, часто в пакете CLOS), чтобы удалить класс из его суперклассов.

  • Вам также необходимо позвонить (setf (find-class 'my-class-to-be-removed) nil).

  • Вам также лучше посмотреть, что у самого класса нет подклассов.

Таким образом, вы можете создать что-то, используя широко поддерживаемые MOP и специфичные для реализации финализаторы.

person Rainer Joswig    schedule 28.09.2012
comment
Вы, безусловно, правы в том, что стандартного пути не существует. Я только что попытался даже просто создать экземпляр класса с (make-instance 'standard-class ...), но я даже не могу заставить его быть GC, хотя я вручную взломал все ссылки на него, которые я смог найти (включая те, которые вы перечислены). Очень жаль. - person Dolda2000; 29.09.2012
comment
@ Dolda2000: я бы попросил конкретные списки рассылки, где разработчики отвечают на вопросы. Они должны быть в состоянии предоставить больше помощи. - person Rainer Joswig; 29.09.2012
comment
Да, я уже сделал это на данный момент. Я просто надеялся, что есть способ сделать это в стандартном CLOS. :) - person Dolda2000; 30.09.2012