2009-04-12 15 views
11

La clase java.lang.Class de Java tiene un método getDeclaredFields que devolverá todos los campos de una clase determinada. ¿Hay algo similar para Common Lisp? Me encontré con algunas funciones útiles, como describir, inspeccionar y escribir símbolos, después de leer, probando las instrucciones en Successful Lisp, Capítulo 10 (http://www.psg.com/~dlamkins/sl/chapter10.html). Pero ninguno de ellos hace lo que haceDeclaredFields.Introspección de clase en Common Lisp

Respuesta

11

Debe usar los slots de clase y/o los slots de clase directa (ambos son de CLOS Metaobject Protocol, MOP). class-slots devuelve todos los slots que están presentes en una clase dada, y class-direct-slots returns, todos los slots se declaran en la definición de clase.

Las diferentes implementaciones de lisp implementan MOP de forma ligeramente diferente; use el paquete closer-mop para tener una interfaz uniforme con MOP.

Ejemplo:

(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 

Ejemplo:

(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)))))