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