Search code examples
smalltalksqueak

overriding compile method in squeak


How can i override the method (of behavior):

  compile: code notifying: requestor trailer: bytes ifFail: failBlock

in the new function (that overrides compile of Behavior) I need to compile the method in the object "code". Do I need to declare it as a class method?

and also, is code (which contains the method to be compiled) a String type?


Solution

  • What is confusing is that the browser does not show the parallel class-side hierarchy...

    You know that true is an instance of class True, so if you send a message to true, it must be understood by it's class True, or one of its superclasses. We can use a browser for browsing that set of messages:

    True browseHierarchy.
    

    If we inquire the inheritance by repeatedly sending superclass messages, that closely matches what the hierarchy browser shows, so far so good :

    True superclass -> Boolean.
    Boolean superclass -> Object.
    Object superclass -> ProtoObject.
    ProtoObject superclass -> nil.
    

    Now what if you send a message to the class True itself? It will be understood by it's class, True class (which is a metaclass True class class == Metaclass).

    But let's inquire the hierarchy of the metaclass True class :

    True class superclass -> Boolean class.
    Boolean class superclass -> Object class.
    Object class superclass -> ProtoObject class.
    ProtoObject class superclass -> Class.
    Class superclass -> ClassDescription.
    ClassDescription superclass -> Behavior.
    Behavior superclass -> Object.
    Object superclass -> ProtoObject.
    ProtoObject superclass -> nil.
    

    Ah Ah! It's deeper than what the browser shows...
    Unsurprisingly, you find Class in this hierarchy, so as to satisfy this:

    "True is a (kind of) class" (True isKindOf: Class) -> true.
    

    Since True class inherits from Behavior, any method of Behavior is understood by all the instances of True class (normally, there is a single one, True class soleInstance == True).

    So, back to the problem, when you want to add an instance-side method to true, you ask to its class to compile a new method:

    True compile: 'asInt ^1'.
    

    Now, true responds to this #asInt message:

    (true respondsTo: #asInt) -> true.
    

    You can then send to any instance of True (again, there should be a single one, True initializedInstance == true):

    true asInt -> 1.
    

    If you want to install a method at class side, that the class True responds to, then you ask to the metaclass, True class, or one of it's superclass:

    Boolean class compile: 'soleInstance ^self initializedInstance'.
    

    Now you can ask:

    True soleInstance -> true.
    

    The lesson is this one: if some tool (like the browser) is just showing a partial view of what an object is, responds to, inherits from, etc..., then try using another tool like:

    True class explore.
    

    And a more important lesson: you're in a live environment, so ultimately use the swiss knife tool - send a message, if it is not understood, some object will kindly tell you ;)

    Now since I've mostly solved your homework, here is a harder problem for you: if you wanted to intercept the compilation of a method compiled at class side, where would you override #compile:...?