On Tue, Oct 4, 2016 at 4:23 AM, CodeDmitry <[email protected]> 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 guess you are referring to... http://www.learncpp.com/cpp-tutorial/811-static-member-variables/ So its fair to analogize to a familiar concept, but you need to remember... Rule 1: *Everything* is an object. which includes class definitions, being instances of Metaclass. So try... Metaclass allInstances inspect. then select one and compare its 'methodDict' and 'thisClass' ==> 'methodDict' with what you see for that class in the System Browser. Notice the ClassDescription superclass to Metaclass has an instance variable 'instanceVariables'. Now one thing that confused me for a moment just now is, if you try... Metaclass allInstances select: [ :mc | mc instanceVariables size > 0 ]. then look at that instance variable 'instanceVariables' it is always nil due to the implementation in Pharo 5 of instance variables as Slots. In Pharo 4 you see actual names of instance variables. btw I'm curious now, does that ivar 'instanceVariables' planned to be removed some time? Now actually (IIUC) a C++ static member variable is most like a "Class Variable" which is defined on the instance side of a class. There are three main variable types to consider when defining a class in Pharo: Instance variables - scoped to instance methods, unique per instance Class Variables - scoped to instance methods & class methods, common to the class and all subclasses and all their instances Class Instance Variables - scoped to class methods, unique per class (i.e. instance of Metaclass) To experience the finer points of these you might try the experiment I describe here... http://forum.world.st/Class-vars-and-inst-vars-of-a-class-tp4749910p4749914.html > I need to make `greeting` an instance variable under "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? The method is bound to an instance of Metaclass, being the class definition. When you add methods or instance variables to the class-side in the Browser, you are adding them to this instance. There is one instance of Metaclass for each class in the system. > Is > it just because it is defined in an "instance" of a "ProtoClass"? I don't understand this question. Can you rephrase after doing the experiment linked above? > > 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). What you are seeing is a copy of the core representation. Try debugging into.... (Greeter class instanceVariables at: 1) paying particular attention to... LayoutClassScope>>visibleSlots LayoutClassScope>>do: > > 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. You are looking at a copy of the core representation. To work through a quick example... take the Morph class definition's first two instanceVariables: 'bounds owner...' and for each of their accessors #bounds and #owner right-click and choose <Inspect Method> then compare each [Bytecode] tab with the first line showing "callPrimitive: 264" or "callPrimitive: 265" respectively. These (and similar) primitives provide the *real* "compiled" access to the instance variables. So that demostration is the equivalent of asking "where are the values in variables stored" for C++ and reviewing its generated assembler code - although our VM provides a level of abstraction. Hopefully the ease of digging from source code down to its compiled bytecode demonstrates another aspect of the power of the Pharo environment. btw, you can see the list of VM primitives here... https://github.com/pharo-project/pharo-vm/blob/36079d9be14542ea9e0d72e5ef57b596bd8aab52/mc/VMMaker.oscog.package/StackInterpreter.class/class/initializePrimitiveTable.st cheers -ben
