saving / loading simple objects

Bob Arning arning at charm.net
Tue Mar 20 12:25:07 UTC 2001


On Mon, 19 Mar 2001 22:01:35 -0700 (MST) Eric Scharff <Eric.Scharff at Colorado.EDU> wrote:
>> > | inFile |
>> > inFile _ (FileStream fileNamed: 'simple2.st').
>> > allComments _ inFile fileInObjectAndCode.
>> > inFile close.
>> >
>> >Is there a "right" way to do this?  Is there some better technique for
>> >this problem that I should probably adopt?
>>
>> Eric,
>>
>> Can you tell us why this feels weird? You have a file that contains the serial representation of some object(s); you read it in and have your object(s) back. What bothers you about that?
>
>
>I guess it was the "AndCode" part I didn't get.  I'm filing out the
>object, not the "source code" for the object (at least I think that's what
>I'm doing.)  What does "and code" mean?  So I guess it's just a vocabulary
>mismatch for me.

Eric,

There are several levels of sophistication to the writing and reading objects in Squeak. 

The first that you discovered, using #storeOn:, works fine for simple objects. Many basic objects can write themselves out in this form and, as a bonus, the resulting file is easily readable by the human eye. This approach, however, starts to become more difficult as your expectations increase. Not every object has a viable #storeOn: strategy and many simply have none implemented. Since it is an ascii representation, it can also become quite large. 

The next level is DataStream. In this approach, a more general solution (#instVarAt: and its cousins) is used so that any object may be described without requiring a #storeOn: method and corresponding #readFrom: be written for each class. Where this method starts to run out of steam is when two objects being written each point to a common third object that shoud retain its identity. As each object tries to describe itself fully, the third object will be written twice and will become two distinct objects when reloaded. The problem gets even worse when the third object points back to the first two.

To handle sharing and cycles, ReferenceStream exists. Here a record is kept of each object written and if the same object is encountered a second (or third or ...) time while writing, then a reference of the form "insert here the object that was written at position xx of the file" is used in place of another full description of the object.

SmartRefStream goes even further by providing some protection against classes changing shape while instances exist as streams outside the image. DataStream achieved its generality by saying: for each object, write the contents of inst var 1, inst var 2,... up to the size of each instance. The obvious weakness of this is that the number of instvars, or their meaning, may have changed between the time the object was written and the time it is to be read back in. SmartRefStream addresses this by beginning the file with a definition of the structure (version number, superclass and the names of the instance variables) of each class represented in the file. Then any mismatch between the current information and the information on the file can be addressed (see methods like #convertToCurrentVersion:refStream:).

Finally (and here we get to your question), it may be that you wish to use the object filed out from one image in another image that is not even aware of the existence of the classes involved. One solution to this is that the file can contain two parts, a normal code fileout decribing the classes and their behavior followed by a serial representation of the objects themselves. The method #fileInObjectAndCode simply accepts that there may be two such parts and is prepared to read either or both. This strategy, BTW, is use in publishing projects that contain code not expected to be a part of the image that will ultimately read the project.

Hope this helps.

Cheers,
Bob





More information about the Squeak-dev mailing list