[Openmcl-devel] [off-topic] Adding a slot to a class using the MOP

Raymond Wiker rwiker at gmail.com
Mon Apr 22 12:19:17 PDT 2013


On Apr 22, 2013, at 19:32 , Ron Garret <ron at flownet.com> wrote:
> Apologies for the non-CCL-related question, but c.l.l. is slow today and I'm really stuck on this.
> 
> I need to dynamically add a slot to a class using the MOP.  There doesn't seem to be a standard add-slot method, so I figure I need to use something like ensure-class.  To do that, I need to reconstruct the argument to :direct-slots from the existing class definition so I can add a slot without disturbing the existing slots.  Before I went down this rabbit hole I thought I'd ask: is there a better/easier way to do this?  Surely I'm not the first person to want to do this.
> 
> Many thanks,
> rg
> 

I did something like the following - but I think I haven't tested it sufficiently to make any guarantees that it works. Requires closer-mop, as a cursory inspection should show :-)



(defclass on-demand-base ()
  ())

(defun slot-definition->list (slot-definition)
  (list :name (closer-mop:slot-definition-name slot-definition)
	:readers (closer-mop:slot-definition-readers slot-definition)
	:writers (closer-mop:slot-definition-writers slot-definition)
	:initargs (closer-mop:slot-definition-initargs slot-definition)
	:initform (closer-mop:slot-definition-initform slot-definition)
	:allocation (closer-mop:slot-definition-allocation slot-definition)
	:type (closer-mop:slot-definition-type slot-definition)
	:documentation (documentation slot-definition t)))

(defun add-slot-to-class (class slot-name)
  (closer-mop:ensure-class 
   (class-name class)
   :metaclass (class-of (class-of class))
   :direct-superclasses (closer-mop:class-direct-superclasses class)
   :direct-slots (cons `(:name ,slot-name
			       :initargs (,(intern (symbol-name slot-name) 
						   (find-package :keyword))))
		       (mapcar #'slot-definition->list 
			       (closer-mop:class-direct-slots class)))
   :direct-default-initargs (closer-mop:class-direct-default-initargs class)))

(defmethod slot-missing (class
			 (object on-demand-base) 
			 slot-name operation &optional new-value)
  (add-slot-to-class class slot-name)
  (ecase operation
    (setf (setf (slot-value object slot-name) new-value))
    (slot-boundp (slot-boundp object slot-name))
    (slot-makunbound (slot-makunbound object slot-name))
    (slot-value (slot-value object slot-name))))




More information about the Openmcl-devel mailing list