Im writing some tests that needs to create classes dynamically. During the
tearDown phase, i remove these classes using #removeFromSystem.

I noticed that running these tests became more and more slower as i kept
adding more tests.
Using "Run Profiled" from Test Runner, i found out
ChangesLog>>#logClassRemoved: was responsible of about 43% of the execution
time:

logClassRemoved: annoucement
        annoucement classRemoved acceptsLoggingOfCompilation ifTrue: [
                self logChange: 'Smalltalk globals removeClassNamed: #',
annoucement
classRemoved name
        ].

Based on that, i overrided #acceptsLoggingOfCompilation on the new classes
to avoid these changes being written down to disk (the classes are
disposable after all), but ChangeSet kept doing it.

I confirmed this by inspecting annoucement classRemoved
acceptsLoggingOfCompilation which returns true, ignoring the overriding
implementation i provided.

#acceptsLoggingOfCompilation overriding implementation seems to be lost
during the #removeFromSystem call. Specifically, during Behavior>>#obsolete,
which is called during

Class>>#obsolete
        "Change the receiver and all of its subclasses to an obsolete
class."
        self == Object
                ifTrue: [^self error: 'Object is NOT obsolete'].
        self setName: 'AnObsolete' , self name.
        Object class instSize + 1 to: self classSide instSize do:
                [:i | self instVarAt: i put: nil]. "Store nil over class
instVars."
        self classPool: nil.
        self sharedPools: nil.
        self hasClassSide ifTrue: [ self theMetaClass obsolete]. <=======
HERE
        self propertyAt: #obsolete put: true.
        super obsolete.

When i checked Behavior>>#obsolete, i found out the method dictionary is
emptied, losing my implementation of #acceptsLoggingOfCompilation

Behavior>>obsolete
        "Invalidate and recycle local methods,
        e.g., zap the method dictionary if can be done safely."
        self canZapMethodDictionary
                ifTrue: [self methodDict: self emptyMethodDictionary].
<======= HERE
        self hasTraitComposition ifTrue: [
                self traitComposition traits do: [:each |
                        each removeUser: self]]

I don't know if this is by design or not, but it seems that the class that
gets announced when removed, is not exactly the same as the original.

Any thoughts/recommendations?



--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Reply via email to