Hi,
Consider the following test case:
CL-USER(1): (use-package :mop) T CL-USER(2): (defclass a () ()) #<STANDARD-CLASS A {794563AA}> CL-USER(3): (defclass b (a) ()) #<STANDARD-CLASS B {62F6FB59}> CL-USER(4): (finalize-inheritance (find-class 'a)) NIL CL-USER(5): (finalize-inheritance (find-class 'b)) NIL CL-USER(6): (class-precedence-list (find-class 'b)) (#<STANDARD-CLASS B {62F6FB59}> #<STANDARD-CLASS A {794563AA}> #<STANDARD-CLASS STANDARD-OBJECT {23309E87}> #<BUILT-IN-CLASS T {100C62C8}>) CL-USER(7): (reinitialize-instance (find-class 'b)) #<STANDARD-CLASS B {62F6FB59}> CL-USER(8): (class-precedence-list (find-class 'b)) (#<STANDARD-CLASS B {62F6FB59}> #<STANDARD-CLASS STANDARD-OBJECT {23309E87}> #<BUILT-IN-CLASS T {100C62C8}>)
The invocation of reinitialize-instance obviously reinitialized the direct-superclasses slot, and thus removed the superclass a.
However, according to the HyperSpec, the general protocol for reinitialize-instance is always that slots for which no initargs are provided through reinitialize-instance should be left untouched. This also restated implicitly in the CLOS MOP specification, for example in the section "Initialization of Class Metaobjects:" The defaulted superclass list is specified to be only assigned during initialization, but not during reinitialization.
Pascal
-- Pascal Costanza
On Dec 3, 2012, at 01:03, Pascal Costanza pc@p-cos.net wrote:
Hi,
Consider the following test case:
CL-USER(1): (use-package :mop) T CL-USER(2): (defclass a () ()) #<STANDARD-CLASS A {794563AA}> CL-USER(3): (defclass b (a) ()) #<STANDARD-CLASS B {62F6FB59}> CL-USER(4): (finalize-inheritance (find-class 'a)) NIL CL-USER(5): (finalize-inheritance (find-class 'b)) NIL CL-USER(6): (class-precedence-list (find-class 'b)) (#<STANDARD-CLASS B {62F6FB59}> #<STANDARD-CLASS A {794563AA}> #<STANDARD-CLASS STANDARD-OBJECT {23309E87}> #<BUILT-IN-CLASS T {100C62C8}>) CL-USER(7): (reinitialize-instance (find-class 'b)) #<STANDARD-CLASS B {62F6FB59}> CL-USER(8): (class-precedence-list (find-class 'b)) (#<STANDARD-CLASS B {62F6FB59}> #<STANDARD-CLASS STANDARD-OBJECT {23309E87}> #<BUILT-IN-CLASS T {100C62C8}>)
The invocation of reinitialize-instance obviously reinitialized the direct-superclasses slot, and thus removed the superclass a.
However, according to the HyperSpec, the general protocol for reinitialize-instance is always that slots for which no initargs are provided through reinitialize-instance should be left untouched. This also restated implicitly in the CLOS MOP specification, for example in the section "Initialization of Class Metaobjects:" The defaulted superclass list is specified to be only assigned during initialization, but not during reinitialization.
Thanks, logged at http://trac.common-lisp.net/armedbear/ticket/277
Rudi
On Dec 3, 2012, at 01:03, Pascal Costanza pc@p-cos.net wrote:
Hi,
Consider the following test case:
CL-USER(1): (use-package :mop) T CL-USER(2): (defclass a () ()) #<STANDARD-CLASS A {794563AA}> CL-USER(3): (defclass b (a) ()) #<STANDARD-CLASS B {62F6FB59}> CL-USER(4): (finalize-inheritance (find-class 'a)) NIL CL-USER(5): (finalize-inheritance (find-class 'b)) NIL CL-USER(6): (class-precedence-list (find-class 'b)) (#<STANDARD-CLASS B {62F6FB59}> #<STANDARD-CLASS A {794563AA}> #<STANDARD-CLASS STANDARD-OBJECT {23309E87}> #<BUILT-IN-CLASS T {100C62C8}>) CL-USER(7): (reinitialize-instance (find-class 'b)) #<STANDARD-CLASS B {62F6FB59}> CL-USER(8): (class-precedence-list (find-class 'b)) (#<STANDARD-CLASS B {62F6FB59}> #<STANDARD-CLASS STANDARD-OBJECT {23309E87}> #<BUILT-IN-CLASS T {100C62C8}>)
The invocation of reinitialize-instance obviously reinitialized the direct-superclasses slot, and thus removed the superclass a.
That was a maze of twisty little :after methods on reinitialize-instance / shared-initialize, should be fixed in r14293. Thanks for the report!
Rudi
armedbear-devel@common-lisp.net