On 27 Dec 2010, at 04:37, Sam Steingold wrote:
Hi, I want to write a macro which would expand to a defclass + some code which uses the resulting class object using mop. e.g. (untested), (defmacro deffoo (class slots) `(progn (defclass ,class () ,slots) (defun foo (x) (list ,@(mapcar (lambda (ds) `(,(car (slot-definition-readers ds)) x)) (class-direct-slots (find-class class)))))))
which should expand (deffoo bar ((a :reader bar-a) (b :reader bar-b))) to something like this: (progn (defclass bar () ((a :reader bar-a) (b :reader bar-b))) (defun foo (x) (list (bar-a x) (bar-b x))))
Alas, CLASS is not defined at read time when (class-direct-slots (find-class class)) and (slot-definition-readers ds) want to be evaluated.
So, how do I do this?
Since a class may be redefined at runtime, you want to use the MOP at runtime anyway. So the code should rather expand into something like this:
(defun foo (x) (loop for slot in (class-direct-slots (find-class 'some-class)) collect (slot-value-using-class (find-class 'some-class) x slot)))
There are ways to tweak this, but the principle should be clear.
If you are really sure that the class doesn't change at runtime, you can alternatively wrap the defclass form into an (eval-when (:compile-toplevel :load-toplevel :execute) ...)
You could of course also decide to parse the slot definition forms yourself.
Pascal