Есть ли способ получить слоты класса?

У меня есть такой класс

(defclass shape ()
 ((color :initform :black)
 (thickness :initform 1)
 (filledp :initform nil)
 (window :initform nil)))

Есть ли в common-lisp функция, как получить список этих слотов, если я знаю только экземпляр этого класса?


person Micky    schedule 22.11.2016    source источник
comment
Тесно связанный: stackoverflow.com/q/38452350/124319   -  person coredump    schedule 22.11.2016
comment
Хорошо, спасибо за ответы. Но у меня другая проблема. Мне нужно знать каждый метод из класса. Даже методы из унаследованного класса. (defclass point (shape) ((x :initform 0) (y :initform 0))) Есть ли способ, как его получить?   -  person Micky    schedule 04.12.2016
comment
См. связанный вопрос.   -  person coredump    schedule 04.12.2016
comment
Но я не могу использовать никакие внешние библиотеки.   -  person Micky    schedule 04.12.2016


Ответы (1)


Многие реализации Common Lisp поддерживают протокол метаобъектов CLOS. Это обеспечивает интроспективные операции для классов, слотов и других метаобъектов.

В LispWorks соответствующие функции напрямую доступны в пакете CL-USER.

CL-USER 139 > (defclass shape ()
                ((color :initform :black)
                 (thickness :initform 1)
                 (filledp :initform nil)
                 (window :initform nil)))
#<STANDARD-CLASS SHAPE 40202910E3>

CL-USER 140 > (mapcar #'slot-definition-name
                      (class-direct-slots (class-of (make-instance 'shape))))
(COLOR THICKNESS FILLEDP WINDOW)

Функции slot-definition-name и class-direct-slots определены протоколом метаобъектов для CLOS и поддерживаются во многих реализациях Common Lisp — только пакет, в котором они находятся, может отличаться. Например, в SBCL их можно найти в пакете SB-MOP.

Из класса мы можем получить список прямых слотов. Прямые слоты — это слоты, которые непосредственно определены для этого класса и не наследуются. Если вы хотите получить список всех слотов, то используйте функцию class-slots.

Слот здесь означает, что мы получаем объект определения слота, который описывает слот. Чтобы получить имя слота, вы должны получить имя из объекта определения слота, используя функцию slot-definition-name.

person Rainer Joswig    schedule 22.11.2016
comment
@Micky См. также github.com/pcostanza/closer-mop. Вы также можете использовать (apropos 'slot-definition-name), чтобы узнать, в каких пакетах эти функции определены в вашей реализации. - person coredump; 30.11.2016
comment
@coredump спасибо, это помогло мне понять, как запустить это на sbcl: - person Pascal; 30.11.2016
comment
(mapcar #'sb-mop:slot-definition-name (sb-mop:class-direct-slots (class-of (make-instance 'shape)))) - person Pascal; 30.11.2016