2016-11-22 15 views
5

У меня есть класс, как этотЕсть ли способ получить слоты класса?

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

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

+1

Близко связано: http://stackoverflow.com/q/38452350/124319 – coredump

+0

Хорошо, спасибо за ответы. Но у меня другая проблема. Мне нужно знать каждый метод из класса. Даже методы из унаследованного класса. '(defclass point (shape) ((x: initform 0) (y: initform 0))) ' Есть ли способ, как его получить? – Micky

+0

См. Связанный вопрос. – coredump

ответ

8

Многие распространенные реализации 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 определяется протоколом Meta Object для CLOS и поддерживается во многих реализациях Common Lisp - только пакете они находятся, может отличаться. Например, в SBCL их можно найти в пакете SB-MOP.

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

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

+1

@ Микки См. Также https://github.com/pcostanza/closer-mop. Вы также можете использовать '(apropos 'slot-definition-name)', чтобы узнать, в каких пакетах эти функции определены в вашей реализации. – coredump

+1

@coredump спасибо, что помогло мне разобраться, как запустить это на sbcl: – Pascal

+1

(mapcar # 'sb-mop: slot-definition-name (sb-mop: class-direct-slots (class-of (make-instance форма»)))) – Pascal