[squeak-dev] References to a removed and reloaded class

Eliot Miranda eliot.miranda at gmail.com
Fri Sep 21 23:14:33 UTC 2012

On Fri, Sep 21, 2012 at 1:13 PM, Levente Uzonyi <leves at elte.hu> wrote:

> I guess we're going off the track with class renaming. The problem I'd
> like to solve is:
> If we remove a class and then add a class to the system with the same
> name, then the methods which were referring to the class before the removal
> are still referring to the same old class. This means that two bindings
> will coexist in the system with the same class name, but pointing to
> different classes.

Let me get this clear.  Surely the methods should still refer to the class
named X after removing and adding back a class named X right?  That can
(and should) be accomplished by moving the binding to Undeclared on
removing it and usiong the binding when declaring the filed-in class.  This
is the way the system used to work and should continue to work.

> How is class renaming related to this?
> One of the possible solutions is to move the removed class's binding to
> Undeclared. When you rename a class, then Class >> #rename: will check if
> there's a binding with the new class name in Undeclared. The problem here
> is that Undeclared doesn't release bindings automatically (when they are
> not referenced by any methods anymore), so bindings gone long ago are still
> lingering in Undeclared, therefore Class >> #rename: (and also Trait
>> #rename:) will #inform: the user about it, which breaks one of the
>> tests.

But that's not a problem.  The set-up for these tests can (and should)
prune unreferenced bindings from Undeclared, either before running or
before complaining of there being bindings in Undeclared.

> But there's another problem with this solution:
> There's a test which tests if a removed class's method is still
> referencing to the class. So replacing the value of the binding with nil is
> not possible.

But that's a bogus test.  Of course the binding's value should be set to
nil.  Either the class has been removed or renamed.  The only thing that
makes sense with remove is to set it to nil.  Rename is more difficult.  It
makes sense to leave it pointing to the new class if the system is running
interactively while the user edits methods to refer to the class under the
new name. Tricky.

If we don't replace the value with nil, then the binding isn't really
> undeclared. So there will be bindings in Undeclared with non-nil value,
> which might have side effects in the system.
> How does the solution I suggested work:
> - when a class is removed, then its binding will be thrown away
> - all methods referring to the class are recompiled. This means that if
> any such method exists, then a new binding will be created in Undeclared
> and all methods will use that new binding.
> The drawback is that mass class removal will be slower. Removing a single
> class will have no noticable difference for the user (20-40ms+the
> recompilation time).

I don't see that this is usefully different from the existing behaviour.
 There seem to me to be two cases, one is renaming a class that is key to
the system functioning, say some class in the compiler.  If the binding is
set to nil then the system will break on trying to compile edited versions
of the methods that refer to the class.  That's tough, but one has to
accept it.  The work-around is to clone the class under the new name (e.g.
file-out, edit, file back in) and move all subclasses under the new class,
and then remove the old class.  The other case is where the class isn't key
and the system keeps running.  In either case, keeping the exsting binding
and setting its value to nil is the correct behaviour; it maintains system
integrity w.r.t. bindings.

> For completeness, here's a list of problems I don't want to solve now:
> - Undeclared holding onto bindings forever

non-problem.  tests that test Undeclared must prune unreferenced bindings
from Undeclared.  The cost is small.  F**ing up Undeclared to make the
tests run fast is a case of the tail wagging the dog.

> - Undeclared introducing Associations for classes instead of
> ReadOnlyVariableBindings

Again if the binding is preserved this won't happen.

> - how class renaming works

has it changed?

> On Fri, 21 Sep 2012, Eliot Miranda wrote:
>  I don't understand.  How else can one use Undeclared?  Any binding in a
>> method which is undefined should be in Undefined.  Hence when a class is
>> removed or when a class is renamed the binding should be moved to
>> Undeclared and left
> Some code uses #at:put: only, others try #includesKey: and #at:ifAbsent:
> which might not work as expected (see above).
>  there, but when a class is renamed we can offer the user the opportunity
>> to redefine methods that refer to the class with the old name (edit the
>> methods to change the name to the new name).
> Should a removed class's binding - which is still pointing to the class -
> be in Undeclared? Will it cause any issues that the binding is still
> pointing to the class?
> Levente
>> One might think that on rename the binding can be reused and its key
>> changed.  But this would leave the methods referring to the new class but
>> with their source naming the old name, hence on recompile the methods would
>> now refer to
>> the binding ... in Undeclared.  So the only correct thing for me is to
>> move the binding to Undeclared, and, if interactive, offer up either a list
>> browser of all references to the class, or an option to edit those methods
>> automatically.
>>       The only reason I know about Class >> #rename: is because a test
>> was failing when I moved the binding to Undeclared. It might not be that
>> hard to find the methods, but it's still extra work to be done. I'll check
>> it out
>>       though, because class renaming is definitely more rare than class
>> removal.
>>       Levente
>> --
>> best,Eliot

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20120921/74d0a89d/attachment.htm

More information about the Squeak-dev mailing list