Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!usc!cs.utexas.edu!uunet!mcvax!ukc!icdoc!qmc-cs!markm From: markm@cs.qmc.ac.uk (Mark Magennis) Newsgroups: comp.lang.smalltalk Subject: Adding instance variables to Sm/V classes Message-ID: <1174@sequent.cs.qmc.ac.uk> Date: 2 Aug 89 10:57:53 GMT Reply-To: markm@cs.qmc.ac.uk (Mark Magennis) Organization: CS Dept, Queen Mary College, University of London, UK. Lines: 105 Expires: References: Sender: Followup-To: Keywords: Here is a method for adding instance variables to classes which have instances. I have successfully used it with Smalltalk/V Mac but there are a few problems with it. 1. Why does it not work with Form class? I postulate that it may be to do with the system expecting certain instances of Form or its subclasses which it keeps (eg Display, Screen) to be a particular size. 2. Are there any other classes for which it won't work? I've tried it on a few classes including DemoClass and a class of my own called Foo with a subclass, SubFoo and an instance of each in the global variables AFoo and ANewFoo. 3. Is there an easy way of changing the superclass of a class? Class has this instance method: subclass:instanceVariableNames:classVariableNames:poolDictionaries: which the handbook claims can be used to 'Create or modify the class [specified in subclass field] to be a subclass of the reciever...'. When I try this I get a 'Cannot change superclass' notifier. 4. If anyone has any comments or sugestions I'd be pleased to hear them. *************************************************************** This code may be used to add instance variables to a class which has instances. I have used it with classes of my own and with DemoClass and it works well, the new instance variables being available for the use of the existing instances. WARNING: THIS WILL NOT WORK FOR ALL CLASSES! In particular it will cause Smalltalk/V to fall over if attempted with class Form. There may be other classes for which it will not work too, particularly 'low level' classes which the system accesses in its own mysterious but probably efficient way. This particular code is for classes with NO subclasses. If subclasses exist then these should be dealt with in the same way unless you can write some code for changing a classes superclass. FIRST STEP: Create the class templates for the temporary class NewFoo and its subclasses by editting those for Foo and its subclasses, altering the class and subclass names and adding whatever new instance variables you want. THEN EXECUTE THE FOLLOWING CODE FOR THE CLASS AND EACH SUBCLASS: |copy| "change instances of Foo into instances of NewFoo" Foo allInstances do: [:anInstance | copy := NewFoo new. 1 to: Foo instSize do: [:index | copy instVarAt: index put: (anInstance instVarAt: index)]. anInstance become: copy]. "copy instances from Foo to NewFoo" Foo allInstances do: [:anInstance | copy := NewFoo new. 1 to: Foo instSize do: [:index | copy instVarAt: index put: (anInstance instVarAt: index)]. anInstance become: copy]. "copy instance methods of Foo into NewFoo" Foo selectors do: [ :each | NewFoo addSelector: each withMethod: (Foo compiledMethodAt: each)]. "copy class methods of Foo into NewFoo" Foo class selectors do: [ :each | NewFoo class addSelector: each withMethod: (Foo class compiledMethodAt: each)]. "copy values of Foo class variables to class variables of NewFoo" Foo classVarNames do: [ :aClassVar | NewFoo classPool at: aClassVar put: (Foo classPool at: aClassVar)]. THEN DO THE FOLLOWING: Foo removeFromSystem. "remove class Foo and rename NewFoo" NewFoo rename: 'Foo'. Also rename the temporary subclasses. *************************************************************** -- UUCP: markm@qmc-cs.uucp | Computer Science Dept ARPA: markm%cs.qmc.ac.uk@nsfnet-relay.ac.uk | Queen Mary College JANET: markm@uk.ac.qmc.cs | Mile End Road Voice: +44 1 975 5241 (Direct Dial) | London E1 4NS