On 10/03/2016 01:23 PM, CodeDmitry wrote:
> I am trying to study Pharo's internals and I am now curious how it stores
> class variables.
>
> I notice that in order to have a class `Greeter` with a "static" variable
> `greeting`, I need to make `greeting` an instance variable under "show show
> the class side" and create a "Getter" and "Setter" for this "instance
> variable".
>
> First thing that confuses me is, why is this called an instance variable if
> this particular "static" method is not bound to any particular instance? Is
> it just because it is defined in an "instance" of a "ProtoClass"?
>
> Second thing that confuses me is, where are these pairs of ("instance
> variable name" => "instance variable value") stored? I know that I can call
>
> Transcript show:
> ((Greeter class) instanceVariables at: 1).
>
> which prints "greeting".
>
> and
>
> Transcript show:
> Greeter instanceVariables class.
>
> which prints "Array"(curious, i expected a Dictionary mapping Strings to
> Object).
>
> Transcript show:
> ((Greeter class) instanceVariables at: 1) class.
>
> prints "ByteSymbol".
>
> Now I am confused, where are the actual values of the "static variables"
> stored? I can find the names, but can't understand where the values are
> hidden.
>
> Can somebody help me understand this?
You've run into one of the core truths of Smalltalk. Both of the
following two statements are true:
1) Every object is an instance of some class.
2) Every class is an object.
---
So, every class must be the instance of some class.
What is the class of a class?
Every time you define a class, you are actually defining a pair of
classes -- the class, and another class to be the class of that class.
The latter is known as a "metaclass" and it is always an instance of
Metaclass. Each Metaclass has exactly one instance, which is a class.
The class defines "instance-side" behavior and variables, and the
metaclass defines "class-side" behavior and variables.
This lets the same rules apply for both normal classes and metaclasses.
For instance, every instance of a class contains a variable for each
variable defined in its class. So if you define a named instance
variable on a normal class, every instance of that class will contain
its own copy of that variable. If you define a named instance variable
in a metaclass, every instance of that metaclass will have its own copy
of that variable. But metaclasses only have one instance, the class, so
there's only one copy of that variable.
Until you subclass that class. The instance-side instance variables are
inherited, and so are the class-side instance variables. So you get a
new metaclass that's a subclass of the old metaclass, and a new class
that's a subclass of the class. This new subclass is distinct from its
superclass, so it gets its *own* copy of the class instance variable,
just like any other object.
This is one way in which class instance variables are different from
static variables. They're not really static at all, but they do have the
lifetime of the class, just like any instance variable has the lifetime
of the object it's in. And the usual rules of access to instance
variables apply, which is why you need getter/setter methods if you want
to access the variable from outside that class object.
I hope this helps you understand Smalltalk a bit better. There are also
class variables, which Nicolas mentioned, and which are quite different,
and which are closer to static variables.
Regards,
-Martin