2009-04-12 3 views
11

Die java.lang.Class-Klasse von Java verfügt über eine getDeclaredFields-Methode, die alle Felder in einer bestimmten Klasse zurückgibt. Gibt es etwas Ähnliches für Common Lisp? Ich stieß auf einige hilfreiche Funktionen wie beschreiben, inspizieren und symbol-plist nach dem Lesen der Anweisungen in Successful Lisp, Kapitel 10 (http://www.psg.com/~dlamkins/sl/chapter10.html). Aber keiner von ihnen tut was getDeclaredFields tut.Klassenintrospektion in Common Lisp

Antwort

11

Sie sollten Class-Slots und/oder Class-Direct-Slots verwenden (beide stammen vom CLOS Metaobject Protocol, MOP). Klassen-Slots gibt alle Slots zurück, die in der gegebenen Klasse vorhanden sind, und Class-Direct-Slots gibt alle Slots zurück, die in der Klassendefinition deklariert sind.

Verschiedene Lisp-Implementierungen implementieren MOP etwas anders; Verwenden Sie das closer-mop Paket, um eine einheitliche Schnittstelle zu MOP zu haben.

Beispiel:

(defclass foo() 
    (foo-x)) 

(finalize-inheritance (find-class 'foo)) ;this is needed to be able to query class slots and other properties. Or, class is automatically finalized when its first instance is created 

(class-slots (find-class 'foo)) 
=> (#<STANDARD-EFFECTIVE-SLOT-DEFINITION FOO-X>) 

(slot-definition-name (first (class-slots (find-class 'foo)))) 
=> FOO-X 

Beispiel:

(defun inspect ((object standard-object)) 
    (inspect-rec (class-slots (class-of object)) object)) 


(defun inspect-rec (slots o) 
    (if(atom slots)() 
    (let ((sn (slot-definition-name (car slots)))) (cons (list sn '=> (slot-value o sn)) (inspect-rec (cdr slots) o)))))