From: Scott L. Burson on
For those with more MOP experience than I, what's the easiest way to
programmatically add a slot to an existing class?

-- Scott
From: Pascal J. Bourguignon on
"Scott L. Burson" <gyro(a)zeta-soft.com> writes:

> For those with more MOP experience than I, what's the easiest way to
> programmatically add a slot to an existing class?

mop:ensure-class.

Yes, you have to recreate the whole class.

You can also do it portably, with (eval `(defclass ...)).


Here is how I do it using ensure-class. The function
ENSURE-CLASS-SLOT adds a slot with slot options adequate for my
application:



(defun convert-to-direct-slot-definition (class canonicalized-slot)
(apply (function make-instance)
(apply (function clos:direct-slot-definition-class) class canonicalized-slot)
canonicalized-slot))


(defun canonicalize-slot-definition (slotdef)
(list :name (CLOS:SLOT-DEFINITION-NAME slotdef)
:readers (CLOS:SLOT-DEFINITION-READERS slotdef)
:writers (CLOS:SLOT-DEFINITION-WRITERS slotdef)
:type (CLOS:SLOT-DEFINITION-TYPE slotdef)
:allocation (CLOS:SLOT-DEFINITION-ALLOCATION slotdef)
:initargs (CLOS:SLOT-DEFINITION-INITARGS slotdef)
:initform (CLOS:SLOT-DEFINITION-INITFORM slotdef)
:initfunction (CLOS:SLOT-DEFINITION-INITFUNCTION slotdef)))


(defun ensure-class-slot (class-name slot-name)
(let ((class (find-class class-name)))
(when class
;; finalize it before calling CLOS:CLASS-SLOTS
(make-instance class-name)
(unless (find slot-name (clos:class-slots class)
:key (function clos:slot-definition-name))
(clos:ensure-class
class-name
:direct-slots
(append (mapcar (function canonicalize-slot-definition) (CLOS:CLASS-DIRECT-SLOTS class))
(list (list :name slot-name
:initform 'nil
:initfunction (constantly nil)
:initargs (list (intern (string slot-name) "KEYWORD"))
:readers (list slot-name)
:writers (list `(setf ,slot-name))
:documentation "Generated by define-association"))))))
class))



--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Scott L. Burson on
On Jun 27, 4:31 pm, p...(a)informatimago.com (Pascal J. Bourguignon)
wrote:
> "Scott L. Burson" <g...(a)zeta-soft.com> writes:
>
> > For those with more MOP experience than I, what's the easiest way to
> > programmatically add a slot to an existing class?
>
> mop:ensure-class.
>
> Yes, you have to recreate the whole class.
>
> You can also do it portably, with (eval `(defclass ...)).
>
> Here is how I do it using ensure-class. [...]

Thanks! Hmm, I was hoping one didn't have to recreate the whole
class. But this should work anyway.

-- Scott
From: Scott L. Burson on
On Jun 27, 4:42 pm, "Scott L. Burson" <g...(a)zeta-soft.com> wrote:
> On Jun 27, 4:31 pm, p...(a)informatimago.com (Pascal J. Bourguignon)
> wrote:
>
> > "Scott L. Burson" <g...(a)zeta-soft.com> writes:
>
> > > For those with more MOP experience than I, what's the easiest way to
> > > programmatically add a slot to an existing class?
>
> > mop:ensure-class.
>
> > Yes, you have to recreate the whole class.
>
> > You can also do it portably, with (eval `(defclass ...)).
>
> > Here is how I do it using ensure-class. [...]
>
> Thanks!  Hmm, I was hoping one didn't have to recreate the whole
> class.  But this should work anyway.

Now that I actually look at your code, I'm not sure what you mean by
"recreate the whole class". I thought you meant that ENSURE-CLASS
needed all the various arguments -- the same ones it would get if
being called by DEFCLASS to initially create the class. But I see
that's not the case.

Too bad the functionality of CANONICALIZE-SLOT-DEFINITION doesn't
happen automatically.

Oh, and I see that CONVERT-TO-DIRECT-SLOT-DEFINITION isn't actually
used here.

-- Scott
From: Pascal J. Bourguignon on
"Scott L. Burson" <gyro(a)zeta-soft.com> writes:

> On Jun 27, 4:42�pm, "Scott L. Burson" <g...(a)zeta-soft.com> wrote:
>> On Jun 27, 4:31�pm, p...(a)informatimago.com (Pascal J. Bourguignon)
>> wrote:
>>
>> > "Scott L. Burson" <g...(a)zeta-soft.com> writes:
>>
>> > > For those with more MOP experience than I, what's the easiest way to
>> > > programmatically add a slot to an existing class?
>>
>> > mop:ensure-class.
>>
>> > Yes, you have to recreate the whole class.
>>
>> > You can also do it portably, with (eval `(defclass ...)).
>>
>> > Here is how I do it using ensure-class. [...]
>>
>> Thanks! �Hmm, I was hoping one didn't have to recreate the whole
>> class. �But this should work anyway.
>
> Now that I actually look at your code, I'm not sure what you mean by
> "recreate the whole class". I thought you meant that ENSURE-CLASS
> needed all the various arguments -- the same ones it would get if
> being called by DEFCLASS to initially create the class. But I see
> that's not the case.

Yes, the only others are the superclasses, the meta-class and the
default-initargs. I assume the superclasses are not modified when we
use ENSURE-CLASS instead of ENSURE-CLASS-USING-CLASS. For the
default-initargs and the meta-class, I don't know, my classes don't
have any. (The documentation would be set separately with (setf
documentation)).


> Too bad the functionality of CANONICALIZE-SLOT-DEFINITION doesn't
> happen automatically.
>
> Oh, and I see that CONVERT-TO-DIRECT-SLOT-DEFINITION isn't actually
> used here.

Good. Better to have unused code, than missing code :-)

--
__Pascal Bourguignon__ http://www.informatimago.com/