On Mon, 27 Dec 2010 09:28:48 -0500, Sam Steingold said:
On Mon, Dec 27, 2010 at 2:02 AM, Pascal Costanza pc@p-cos.net wrote:
On 27 Dec 2010, at 04:37, Sam Steingold wrote:
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.
no, these classes will not change at run time (they are actually structs); and even if they will, I will be using deffoo for that.
If you are really sure that the class doesn't change at runtime,
I am.
you can alternatively wrap the defclass form into an (eval-when (:compile-toplevel :load-toplevel :execute) ...)
nope. my macro calls MOP functions at macroexpansion time, so this eval-when will not help me.
This might work (by delaying the MOP functions until the defclass has been evaluated at compile-time).
(defmacro list-all-slot-values-of-class-name (class) `(list ,@(mapcar (lambda (ds) `(,(car (slot-definition-readers ds)) x)) (class-direct-slots (find-class class)))))
(defmacro deffoo (class slots) `(progn (eval-when (:compile-toplevel :load-toplevel :execute) (defclass ,class () ,slots)) (defun foo (x) (list-all-slot-values-of-class-name ,class))))
I wonder if the deprecated #, will help me.
Using load-time-value would be better.