|
Recently I took a look at the Global Keys project of Tony Fleig and noticed something strange. The package GlobalKeys makes some class extensions to the HandMorph class, extensions which are accessors to an instance variable. Since instance variable can't be included in class extensions, the variable appears as undeclared instead.
HandMorph>>globalKeystrokeHandler "class extension"
^globalKeystrokeHandler "is an undeclared variable"
HandMorph>>globalKeystrokeHandler: aOneArgBlock
globalKeystrokeHandler := aOneArgBlock
However, when loading the package, class side initialization uses the mutator #globalKeystrokeHandler: to set a default behavior for 'World activeHand' (an instance of HandMorph) and... it works! No error, it just works as if the instance variable is well defined and can be accessed without problem.
GlobalKeys class>>setHandMorphHook "called by class initialization"
World activeHand globalKeystrokeHandler: [ :ev |
| retval |
retval := false. "..." ]
How can it be that the first invocation of #globalKeystrokeHandler: in #setHandMorphHook does not crash?
Try the following:
Gofer new
squeaksource: 'GlobalKeys';
version: 'GlobalKeys-TonyFleig.9';
load
Print it:
World activeHand globalKeystrokeHandler
---> print the source of a code block
Now debug the above snippet and proceed *into* globalKeystrokeHandler
Print it again ----> print nil
as if the code was recompiled once processed by the debugger
You can also add the instance var globalKeystrokeHandler, recompile, it will be set to nil.
|