Search code examples
pharo

Change superclass programmatically


I want to change some class' superclass from code, what is the best way to do it?

The one thing that comes into my ming is

NewSuperclass subclass: #MyClass
  "…with all the MyClass vars…"

but this looks a bit strange.


Solution

  • As mentioned, the most straightforward way to do it is to redefine the class via evaluating a new class definition. However, changing the superclass in this way will cause the compiler to recompile all code in the class and its subclasses. Sometimes this can be a problem, e.g. redefining core classes that the system uses during the recompile.

    I had occasion to redefine the superclass of Float just yesterday, and had to avoid recompilation for precisely this reason. To completely change the superclass one also needs to remove the class from the subclasses of its old parent and add it to the subclasses of the new parent, /and/ one must do that with the class's metaclass. So here is a full example:

    "Reparent the class and its metaclass"
    Float superclass: LimitedPrecisionReal.
    Float class superclass: LimitedPrecisionReal class.
    "Remove the class and its metaclass from the subclasses of their old parent"
    Number removeSubclass: Float.
    Number class removeSubclass: Float class.
    "Add the class and its metaclass to the subclasses of their new parent"
    LimitedPrecisionReal addSubclass: Float.
    LimitedPrecisionReal class addSubclass: Float class.
    

    Perhaps this should be a method, such as changeSuperclassTo: ? But remember it is dangerous. The ClassBuilder recompiles code in this sutuation for good reason. Changing the superclass without recompiling is valid only in special circumstances, that no inst vars are added or removed, that the class's compilation scope is unchanged, etc.