Hi all.
I've found myself in the unfortunate position of needing to work with Metaclasses for my own project! I'll spare the details; you can email me directly if you want them :-). Why does the following happen?: m := Metaclass new. " Construct the Metaclass instance for my new class" c := m new. "Make my new class". The code will evaluate fine, but if you try to do anything with c, CPU usage hits 100% and I can't seem to break out of it. Ideas? I suspect it is something like m not being initialised properly with a superclass etc. I'm taking my inspiration from ClassBuilder>>privateNewSubclassOf:. Michael. |
Michael:
You will find that your new Metaclass ("m,") although it has a MethodDictionary and a superclass, does not have the right MethodDictionary or superclass to actually create any instances. That's why the code in ClassBuilder does the following: privateNewSubclassOf: newSuper "Create a new meta and non-meta subclass of newSuper" "WARNING: This method does not preserve the superclass/subclass invariant!" | newSuperMeta newMeta | newSuperMeta := newSuper ifNil:[Class] ifNotNil:[newSuper class]. newMeta := Metaclass new. newMeta superclass: newSuperMeta methodDictionary: MethodDictionary new format: newSuperMeta format. ^newMeta new If you provided the new Metaclass with a MethodDictionary with the right CompiledMethods in it, you wouldn't need to give it a superclass. But the usual practice is to make the superclass of a Metaclass instance be either Class (which is an instance of an instance of Metaclass) or else some other already-provisioned Metaclass instance. Be forewarned: You're dealing with the "moebius strip" of Smalltalk's class-metaclass metamodel, and it's easy to get yourself very confused. Careful thought will be required to avoid error. Note: The class of Metaclass is 'Metaclass class,' and the class of 'Metaclass class' is Metaclass. This provides the transitive closure of Smalltalk's metamodel. The superclass of a root class is nil, the superclass of the metaclass of a root class should normally be Class, so that the instance of the metaclass instance (a root class) will inherit "Class behavior" from Class itself. --Alan -----Original Message----- From: [hidden email] [mailto:[hidden email]] On Behalf Of Michael van der Gulik Sent: Sunday, March 19, 2006 1:35 PM To: [hidden email] Subject: Metaclass issues. Hi all. I've found myself in the unfortunate position of needing to work with Metaclasses for my own project! I'll spare the details; you can email me directly if you want them :-). Why does the following happen?: m := Metaclass new. " Construct the Metaclass instance for my new class" c := m new. "Make my new class". The code will evaluate fine, but if you try to do anything with c, CPU usage hits 100% and I can't seem to break out of it. Ideas? I suspect it is something like m not being initialised properly with a superclass etc. I'm taking my inspiration from ClassBuilder>>privateNewSubclassOf:. Michael. |
In reply to this post by Michael van der Gulik
On Mar 19, 2006, at 4:11 AM, Alan Lovejoy wrote: > If you provided the new Metaclass with a MethodDictionary with the > right > CompiledMethods in it, you wouldn't need to give it a superclass. > But the > usual practice is to make the superclass of a Metaclass instance be > either > Class (which is an instance of an instance of Metaclass) or else > some other > already-provisioned Metaclass instance. Michael, Alan is right. At an absolute minimum, objects must be able to respond to #doesNotUnderstand:, either in their own method dictionary, or via their superclass. If not, you get a recursive #doesNotUnderstand: loop, which might be the cause of your VM crash. Colin |
In reply to this post by Michael van der Gulik
Thanks, Alan (and Colin).
And thanks for the warning, too! I've already learned to save my image *before* running any tests! Michael. Alan Lovejoy wrote: > Michael: > > You will find that your new Metaclass ("m,") although it has a > MethodDictionary and a superclass, does not have the right MethodDictionary > or superclass to actually create any instances. That's why the code in > ClassBuilder does the following: > > privateNewSubclassOf: newSuper > "Create a new meta and non-meta subclass of newSuper" > "WARNING: This method does not preserve the superclass/subclass > invariant!" > | newSuperMeta newMeta | > newSuperMeta := newSuper ifNil:[Class] ifNotNil:[newSuper class]. > newMeta := Metaclass new. > newMeta > superclass: newSuperMeta > methodDictionary: MethodDictionary new > format: newSuperMeta format. > ^newMeta new > > If you provided the new Metaclass with a MethodDictionary with the right > CompiledMethods in it, you wouldn't need to give it a superclass. But the > usual practice is to make the superclass of a Metaclass instance be either > Class (which is an instance of an instance of Metaclass) or else some other > already-provisioned Metaclass instance. > > Be forewarned: You're dealing with the "moebius strip" of Smalltalk's > class-metaclass metamodel, and it's easy to get yourself very confused. > Careful thought will be required to avoid error. > > Note: The class of Metaclass is 'Metaclass class,' and the class of > 'Metaclass class' is Metaclass. This provides the transitive closure of > Smalltalk's metamodel. The superclass of a root class is nil, the > superclass of the metaclass of a root class should normally be Class, so > that the instance of the metaclass instance (a root class) will inherit > "Class behavior" from Class itself. > > --Alan > > -----Original Message----- > From: [hidden email] > [mailto:[hidden email]] On Behalf Of Michael > van der Gulik > Sent: Sunday, March 19, 2006 1:35 PM > To: [hidden email] > Subject: Metaclass issues. > > Hi all. > > I've found myself in the unfortunate position of needing to work with > Metaclasses for my own project! > > I'll spare the details; you can email me directly if you want them :-). > Why does the following happen?: > > m := Metaclass new. " Construct the Metaclass instance for my new class" > c := m new. "Make my new class". > > The code will evaluate fine, but if you try to do anything with c, CPU usage > hits 100% and I can't seem to break out of it. > > Ideas? I suspect it is something like m not being initialised properly with > a superclass etc. I'm taking my inspiration from > ClassBuilder>>privateNewSubclassOf:. > > Michael. > > > > > |
Free forum by Nabble | Edit this page |