Search code examples
javareflectionlispcommon-lispintrospection

Class introspection in Common Lisp


Java's java.lang.Class class has a getDeclaredFields method which will return all the fields in a given class. Is there something similar for Common Lisp? I came across some helpful functions such as describe, inspect and symbol-plist after reading trying out the instructions in Successful Lisp, Chapter 10 (http://www.psg.com/~dlamkins/sl/chapter10.html). But none of them do what getDeclaredFields does.


Solution

  • You should use class-slots and/or class-direct-slots (both are from CLOS Metaobject Protocol, MOP). class-slots returns all slots that are present in given class, and class-direct-slots returns all slots are declared in class definition.

    Different lisp implementations implement MOP slightly differently; use closer-mop package to have uniform interface to MOP.

    Example:

    (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
    

    Example :

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