I need to create a class at run-time, possibly without resorting to eval. Knowing that the metaclass protocol is not fully standardized in Common-Lisp, after browsing through the The Common Lisp Object System MetaObject Protocol, I tried the following code to create a class, instantiate it, and set a slot value of the instance to a number:
(defparameter *my-class*
(make-instance 'standard-class
:name 'my-class
:direct-slots '((:name x :readers (get-x) :writers ((setf get-x))))))
(defparameter *my-instance* (make-instance *my-class*))
(setf (get-x *my-instance*) 42) ;; => 42
Unfortunately this code works correctly on SBCL, but not on CCL, where the class creation seems to work, but the instance creation (make-instance *my-class*)
causes the following error:
There is no applicable method for the generic function:
#<STANDARD-GENERIC-FUNCTION INITIALIZE-INSTANCE #x30200002481F>
when called with arguments:
(#<error printing CONS #x302001A9F6A3>
[Condition of type CCL:NO-APPLICABLE-METHOD-EXISTS]
I tried looking at closer-mop package, that should hide the differences between the various implementations for the meta-object protocol, but I could not find any function or class useful to my scope.
So the question is: is there a portable way of creating a class and instantiating it at run time by using directly the metaclass level of CLOS?
CCL seems to require that you manually specify the direct superclasses as well.
(defparameter *my-class*
(make-instance 'standard-class
:name 'my-class
:direct-slots '((:name x :readers (get-x) :writers ((setf get-x))))
:direct-superclasses (list (find-class 'standard-object))))