Metaclass issues.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Metaclass issues.

Michael van der Gulik
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.


Reply | Threaded
Open this post in threaded view
|

RE: Metaclass issues.

Alan L. Lovejoy
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.




Reply | Threaded
Open this post in threaded view
|

Re: Metaclass issues.

Colin Putney
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

Reply | Threaded
Open this post in threaded view
|

Re: Metaclass issues.

Michael van der Gulik
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.
>
>
>
>
>