[closer-devel] Redefining classes

Pascal Costanza pc at p-cos.net
Thu Dec 1 16:21:46 UTC 2005


Hi Michael,

On 1 Dec 2005, at 11:22, Michael Weber wrote:

> Hi,
>
> this mailing list was the closest (hah!) I could find to a (still
> active) MOP discussion list.  If my question is off-topic, I'd love
> to hear where else to go.

The newsgroup comp.lang.lisp would also be appropriate, although your  
question is certainly on-topic here as well. After all, it's a  
question whose answer will clarify how to interpret the CLOS MOP  
specification.

> I seem not to understand some aspects of class redefinition.  Suppose
> the following situation:
>
> (defclass foo ()
>   (...)
>   (:metaclass foo-metaclass))
>
> (defclass foo-1 (foo)
>   (...)
>   (:metaclass foo-metaclass))
>
> If I redefine FOO later on to add or remove slots, it gets
> reinitialized, and I have
>
> (defmethod shared-initialize :after ((class foo-metaclass) slot-names
> 	                             &rest initargs
>                                      &key &allow-other-keys)
>  ...)
>
> which recalculates some slot-based information for FOO then.
>
> However, FOO-1 is left unchanged, which surprised me a little.  I
> would have expected that it gets reinitialized as well, thus giving
> the above initializer a chance to recalculate information for FOO-1,
> too.
>
> I am using CLASS-SLOTS in the FOO-METACLASS specific initialization to
> get to the slots of FOO-1, but that includes inherited slots from FOO
> as well.  Clearly, after redefinition of FOO, that information might
> be out of date for FOO-1.

I don't think it will be out of date for FOO-1. CLASS-SLOTS gives you  
the set of effective slots, that is, all slots that are accessible in  
a class. The class initialization/reinitialization phase is, among  
other things, responsible for determining the direct slots - the ones  
that directly defined for a given class, without the inherited slots  
- but _not_ for determining the effective slots. The effective slots  
are determined by the class finalization protocol, that is, by the  
generic function finalize-inheritance.

So when you reinitialize a class, it's not reinitialize-instance that  
is being called for all subclasses, but finalize-inheritance. At  
least that is what should happen.

Note that it is not specified when this happens. According to the  
class redefinition specification in ANSI Common Lisp, it is strictly  
only necessary before the first instance of a given subclass is   
accessed, so just before update-instance-for-redefined-class is first  
called - see Section 4.3.6 in the HyperSpec. I don't know whether any  
CLOS implementation takes advantage of that freedom. (It seems to me  
that only Allegro Common Lisp takes the freedom to delay calling  
finalize-inheritance after initializing a class in the first place,  
so I would guess that this would also only happen in Allegro if at  
all. But that's only a guess.)

> Is there a way to invalidate and reinitialize all subclasses?  I would
> assume that that's a common issue.

I don't think there's a need to do that. Or do you have evidence that  
something's going wrong here? If so, could you be more specific -  
including which Common Lisp implementation you use?

> Or, if not, is there a (predefined) way to get only those effective
> slots of a class which are not inherited?  I could use
> CLASS-DIRECT-SLOTS, but that seems wrong, as I am supposed to work
> with effective slots, no?

I don't understand that question. The direct slots are exactly the  
slots defined for a given class - without the inherited slots - so if  
they are what you're interested in you should be fine.

Maybe it's a good idea to tell us your overall goal - what is it that  
you are actually trying to achieve?


Cheers,
Pascal

-- 
Pascal Costanza, mailto:pc at p-cos.net, http://p-cos.net
Vrije Universiteit Brussel, Programming Technology Lab
Pleinlaan 2, B-1050 Brussel, Belgium







More information about the closer-devel mailing list