Re: duplicate of classes (deep copy)

Jaap Vermeulen (jaap@sequent.com)
Thu, 30 Sep 93 11:40:00 PDT

| Also note that a naive deep copy can get in trouble if there are
| reference loops. I don't know how smalltalk solves this. Probably by
| keeping track of objects already copied during the deep copy? But I
| presume it will also be possible to override the dup method for a
| particular class, which may spoil the administration used...

Smalltalk doesn't have deepCopy, only shallowCopy. The regular copy will do
a shallowCopy followed by a postCopy (to break dependents and other book
keeping you need to do after the copy). You can redefine copy to whatever
you like if you need it (with care, of course).

| One problem with this: if a class has an __init__() method, it will be
| called by the "x.__class__()" in dupinstance(). This may or may not
| be what is desired; moreover it will fail with probablility one if the
| __init__() takes one or more arguments. The effect is that classes
| with such an __init__() method are forced to define their own dup()
| method (which still will call the __init__() method, but can call it
| with the proper arguments. Possibly it can be given a special
| argument signalling to initialize the object from a similar one, like
| copy constructors in C++.

Smalltalk provides two methods for all basic operations. For new objects,
the default method is 'new'. New is redefined by those objects that need
additional initialization. However, there is always 'basicNew', which you
should *never* redefine. With a structure like that you can circumvent the
problems outlines above.

BTW: the way that operations like 'new' are redefined is by first calling
the same operation in the superclass, and then performing your own
initialization. So, if your superclass redefined 'new', the superclass
initialization will always happen first. In Python code (just to
illustrate):

class topObject():
def new(self): return self
def basicNew(self): return self
def copy(self):
new = self.shallowCopy()
return new.postCopy()

class bar(topObject):
def new(self):
self = foo.new(self)
return self.initialize()

instance = bar().new()
another_instance = instance.copy()

| Note that this problem has similarities with the problems one
| encouters when trying to implement generic persistent objects in
| Python. There, too, one of the problems is to define what the
| semantics should be in the light of objects that may contain
| references to open files, windows, network connections, etc., and to
| what extent sharing of sub-objects is incidental or essential. I have
| a feeling that this is because Python mixes mutable and immutable
| objects and also allows "opaque" objects with arbitrary semantics
| (e.g. defined by extension modules).

Smalltalk solves this by giving object that need it the possibility to
'shutdown' or 'instal' themselves. Given that the current state of Smalltalk
is saved in the Smalltalk image, objects such as files and the window
subsystem are notified in case the image is saved. They take the necessary
precautions, the image gets saved, and then those objects get one of two
messages. One is that the current session is still active, and the other is
that a new session using the saved image started, which means they have to
restore their state. For files, this means that they try to reconnect to all
the files that were open when the image was saved. For windows, it means
that all windows are reopened at the same place with the same contents. Of
course there is some logic in place for conditions, such as restarting the
image on a different platform where the files don't exist, or the display
has a different size. Like I do with my Smalltalk image all the time. I
shuttle it around between UNIX, DOS and Mac. The only thing that differs on
these platforms is the virtual machine (binary).

So, in a way you get object persistence for free. However, to save objects
outside the Smalltalk image, there is the BOSS facility, the Binary Object
Storage Stream, which saves objects and all objects they reference
unambiguously.

| Maybe Jaap has some thoughts or opinions on this?

Sorry it took me so long. I was busy. :-)

-Jaap-