[BUG] StringMorph needs textColor inst var and uses color inst var wrongly?

Scott Wallace scott.wallace at squeakland.org
Sat May 4 20:58:56 UTC 2002


Ken,

As soon as you submit a modified class definition, all existing 
instances of the class (and of its subclasses) are mutated.  If 
you've added an instance variable, all instances immediately acquire 
the new instance variable, with value nil.

So if you want your redefined class to be robust in the face of 
pre-existing instances, just make certain the new code you write will 
not fail when run on behalf of those pre-existing instances that have 
nil values in the slot you added.

One straightforward approach -- which you have alluded to -- would be 
to define #textColor as something like:

textColor
	^ textColor ifNil: [textColor := Color black]

... do this *before* you modify drawOn:.  Then, in your drawOn:, use 
this getter rather than a direct inst-var reference.


Use of a lazy getter such as this is traditional, but not essential. 
Alternatively, you could have also have done this safely directly 
within your #drawOn: method itself, if you preferred, as long as you 
were careful to handle the nil case there.

   -- Scott


At 2:28 PM -0500 5/4/02, Ken Causey wrote:
>Yes.  I belive the exact problem is that I added a new inst var 
>(textColor) to StringMorph, and then modified StringMorph>>drawOn: 
>so that this inst var was used as the color for the text.  Any 
>existing instances freaked out at that point.  It's not clear to me 
>what happens with existing instances when new inst vars are added to 
>the class.  I'm guessing the existing instances had no such instance 
>variable textColor and when the new drawOn: method tried to use 
>it...  Otherwise, even if the instance var existed, it's value would 
>have bin nil, still not good.
>
>However, it now occurs to me that I may have avoided this if I had 
>simple not made the mistake of referencing the instance variable 
>directly and had instead use the getter (with lazy initialization) 
>that I had taken the trouble to create.  IF (big assumption) the new 
>instance variable existed then lazy initialization would have filled 
>it in.
>
>So, the question is, if you modify the Class definition (add 
>instanced variable for example) are existing instances still based 
>on the old definition?  If so (which I suspect is the case) how does 
>one go about recreating these instances for such ubiquitous classes 
>such as StringMorph?
>
>Theory #1:  Modify the class definition to add the instance 
>variable. Don't modify any existing methods to use this method. 
>Save the image and quit the image.  Restart the image.  Be sure to 
>make use of lazy initialization to make sure that any access to the 
>variable returns a useful value.  Modify all methods appropriately.
>
>What do you think?  Would this do the job?
>
>Thanks,
>
>Ken Causey
>
>Scott Wallace wrote:
>>Ken,
>>
>>It's not that objects can't happily mutate on the fly in Squeak -- 
>>that happens all the time.  It's very common for people to add 
>>instance variables to classes that have existing instances.  Squeak 
>>is extremely robust about this.
>>
>>The problem, rather, is more likely to be that the code you wrote 
>>in your modified StringMorph drawOn: method raised an error.
>>
>>Because StringMorphs are used in the title bars of System Windows, 
>>every attempt to report this error -- or any error -- will result 
>>in a fresh error (since a pre-debug Notifier is itself a 
>>SystemWindow, and hence needs to have a StringMorph drawn in its 
>>title bar.) That's probably why your image ran away from you.
>>
>>   -- Scott
>>
>>
>>At 4:44 PM -0500 5/3/02, Ken Causey wrote:
>>
>>>/me replies to himself.
>>>
>>>So okay, I decide to play with fixing this.  Add an inst var of
>>>textColor, add lazy init getter and setter.  Modify drawOn: and whoops!
>>>my image is locked and alt-. doesn't help.  Clearly I've swept the rug
>>>out from under a host of existing StringMorphs in my image.
>>>
>>>So, how do I go about making this sort of change?  I can't at the moment
>>>see how to modify the image and not having StringMorph instances active.
>>>
>>>Ken
>>>
>>>On Fri, 2002-05-03 at 16:09, Ken Causey wrote:
>>>
>>>>  I'm playing around and try some code like:
>>>>
>>>>  (s _ SystemWindow labelled: 'Boogah')
>>>>     openInHand.
>>>>  s addMorph: (StringMorph new
>>>>         contents: 'Comments:';
>>>>         color: Color black)
>>>>     frame: (0 at 0.0 corner: 1 at 0.2).
>>>>
>>>>  And I don't see any StringMorph in the window.  I start looking around
>>>>  and find that the color is set to transparent.  Which would be find
>>>>  except that StringMorph uses color as it's text color, not the primary
>>>>  (i.e. background) color.  Seems to be this is incorrect.  Shouldn't
>>>>  there be a textColor attribute used as the color to draw the text and
>>>
>>>  > color be used as the background color?
>>>  >
>>>  > Ken
>>>  >
>>>  >




More information about the Squeak-dev mailing list