Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!cs.utexas.edu!sun-barr!apple!voder!cullsj!david From: david@cullsj.UUCP (David Taylor) Newsgroups: comp.lang.smalltalk Subject: Re: Smalltalk/V: adding new instance variable Summary: A messy solution (LONG) Message-ID: <620@cullsj.UUCP> Date: 23 Jun 89 21:46:42 GMT References: <17@piyopiyo.hatori.t.u-tokyo.JUNET> Organization: Cullinet Software, San Jose, CA Lines: 49 Welcome to Smalltalk/V's biggest headache. I've found this the number one pain in an otherwise great system. And let's face it - when you're prototyping you're going to run into this all the time because you're constantly changing the class definition. I'm not a Smalltalk guru, so I can't say why the user can't elect to propagate the new variable to existing instances. The only solution I've found is a messy one; i.e. to unload, modify and reload the class: 1 - Create a temporary class that has both the original and new instance variables. 2 - Transform all instances of the original class to become instances of the temporary class. 3 - Remove the original class and create a new class of the same name with the original and new instance variables. 4 - Transform all instances of the temporary class to to become instances of the new class. (Optionally) Remove temporary class. Now I'm assuming that the new class must have the same name as the original. Otherwise, skip steps 3 and 4. An example is in order. I don't have my Smalltalk/V book with me, so I'll just have to pseudocode an example. Assume we want to add a new instance variable, 'height', to class Human that has instance variables 'weight' and 'age'. 1 - Create class TempHuman. Add height, weight, and age to its instance variables. You can either do this manually by editing the class definition or do: TempHuman instVarNames: Human instanceVariableString, 'height'. 2 - Human allInstances do: [ :each | each become: TempHuman ]. "Now assign original values to variables of TempClass " "Here I assume that methods exist to get/put instance variable values and that those methods have the same name as the corresponding variable" Human instVarNames do: [ :aName | TempHuman perform: aName with: (Human perform: aName) ]. 3 - Remove class Human. Then create class Human: Human instVarNames: TempHuman instanceVariableString 4 - TempHuman allInstances do: [ :each | each become: Human ]. TempHuman instVarNames do: [ :aName | Human perform: aName with: (TempHuman perform: aName) ]. I believe instVarNames answers an Array of Symbol and instanceVariableString answers a String of blank-seperated names, but I'm not sure. PLEASE, PLEASE, PLEASE if you find an easier way, let me know. Thanks P.S. I'm assuming that when you get the 'Has Instances' message that you don't want to kill existing instances by saying Human allInstances [:each | each become: String new ]