[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Changing default slot values (or initforms)

   Date: Tue, 3 Jul 90 17:55:01 PDT
   From: eero@helmholtz.arc.nasa.gov (Eero Simoncelli)

   Is there a mechanism for altering the initforms of slots of an
   existing class?  I couldn't find this in the spec, but it seems
   like a useful ability.

Its a little difficult for me to tell exactly what you are asking.  It
seems like it could be one of two things, and the answer is different
in each case.

  1) Is there a mechanism for changing the initform of a slot
     of a class that I HAVE DEFINED.

The answer here is YES, and there are two ways to do it.  One way is to
take the original defclass form, edit it to have the new initform, and
then re-evaluate it.  CLOS makes it clear that this is well-defined.
Any instances created afterwards will use the new initform.

Using the metaobject protocol (if your implementation supports it), it
is possible to write a function which will change the initform of any
given slot.  It would go something like this:

(defun change-initform (class slot-name form fn)
  (let* ((slots (class-direct-slots class))
         (slot (find slot-name slots :key #'slot-definition-name))
         (new (make-instance (class-of slot)
                :name         (slot-definition-name slot)
                :allocation   (slot-definition-allocation slot)
                :initform     form
                :initfunction fn
                :type         (slot-definition-type slot)
                :readers      (slot-definition-readers slot)
                :writers      (slot-definition-writers slot))))
    (reinitalize-instance class
                          :direct-slots (cons new (remove slot slots)))))

So, give a class FOO, with a slot X, you could change its initform to 1
by doing: (CHANGE-INITFORM (FIND-CLASS 'FOO) 'X '1 #'(LAMBDA () 1)).

  2) The second question you could be asking is how can I
     change an initform of a slot of a class that I DID NOT

The criticial point here is that you probably shouldn't.  In general,
slots tend to be internal, implementation details of a class.  Most
often, you shouldn't even know what slots a class you didn't define has.
You certainly shouldn't be mucking around with internal things like what
the initforms are.  If the implementor of the class wanted to give you
this kind of control, they would have defined an initarg for the class.
Given that, you could define your own subclass of that class and use the
:default-initargs mechanism to get whatever default behavior you want.