Reflecting on self, super and thisContext

September 3, 2020 ☼ pharo

If you follow the changes in Pharo 9, you might be aware that we are unifying all objects describing variables into one class hierachy. You can check the subclasses of class Variable to see the current state.

There are three very special variables: self, super and thisContext (true, false and nil are modelled as Literals, just if you wonder why they are not in this list).

We thus now have SelfVariable, SuperVariable and ThisContextVariable, with a shared superclass ReservedVariable. There is just one instance of each in the system (for example: SelfVariable instance) and they are used as semantic annotations of the AST. You can ask any RBVariableNode for it’s variable, and if it is a self’, it will return the one instance of SelfVariable.

Like all other variables, they provide a useful API to query the system:

SuperVariable instance usingMethods size "6978"

Thus 6978 methods access super. How does this compare to self?

SelfVariable instance usingMethods size "98600" 

As expected, we refrence self much more then super! Actually, we reference it in lots of methods!

Object environment allMethods size - SelfVariable instance usingMethods size "33107"

And what about thisContext?

ThisContextVariable  instance usingMethods size "245"

As expected, thisContext is not used very often. And that is good: it is, in the end, magic that should not be used just everywhere.

Besides finding the methods, we can go down to the AST level:

ThisContextVariable  instance asNodes size "403"

So thisContext is referenced 403 times in 245 methods.

The system was refactored to make introducing new reserved variables as simple as adding a subclass to ReservedVariable. Thus, if you want to experiment with thisProcess’ or thisImage’, it is now very easy to do.

How to do that for real will be for another post.