TADS 3
· createInstance() returns an instance
of an object. The superclass of the instance is the original object, and the
instance has the same property references as the original.
· createClone() returns a “shallow” copy of an object, having the same
superclasses as the original (but the original is not a superclass of the
copy), and the same property references.
· simClone() returns a “deeper” copy of an object, having the same
superclasses as the original, but with simulated objects for certain property references based on
class.
Now
suppose we have a game puzzle that involves dropping objects into a
“simulation” or “cloning” machine. Objects are placed on a tray and scanned. A
“duplicate” of the object then materializes inside a comparment.
Simple?
The following explains why SimClone is an author’s best choice for some kinds
of situations.
The
problem is this. Since an instance is derived from the original, any changes
made to the original are reflected in the copy. Not a very stable copy. Complex
objects are especially unstable. If
TADS 3
provides a shallow cloning method, createClone(). According to the t3obj.htm, the method “creates a new object
that is an identical copy of this object.
The new object will have the same superclasses as the original, and the
identical set of properties defined in the original.”
This means that the clone
refers to all of the same objects as the original,
which is not always desirable.
For
example, suppose we have a tray with a bottle of milk on it.
tray: Surface 'tray' 'tray' @me;
+Container 'glass bottle' 'glass
bottle';
++Food 'milk' 'milk';
A “shallow”
clone of the tray can be produced by:
cl = tray.createClone();
Creating
a clone of the tray using createClone() produces a new tray object, but the cloned tray
references the same bottle of milk as the original. The bottle of milk,
therefore, exists in two places at once!
What
we were really after was a clone of the tray that also simulated the bottle of
milk. This is where SimClone comes in.
In
order to accomplish this kind of simulated cloning we have to employ object-oriented
“deep” cloning techniques involving creating a method on object classes so that
they handle the specifics of their own cloning. Each class that requires
special cloning must provide a simClone() method to handle the desired cloning and reference
resolution.
Since
the tray example above is quite common, requiring specialized handling of the
containment relationship, SimClone provides deep cloning for TadsObject and Thing
classes that copies content objects and maintains a valid containment relationship
between the cloned objects and their locations.
Now we
can create a simulation clone of the tray and all of its contents. In other
words create a new tray, and on that new tray a new glass bottle, and in that
new glass bottle, new milk.
To do
this we execute the simClone() method on tray:
local cl = tray.simClone();
What
is produced is a dynamically-created object that will look something like the
following in the TADS 3 Workbench Local Variables View:
Expression |
Value |
-cl |
obj#1d59
(Surface) |
|-location |
me |
|-contents |
[obj#1d57
(Container)] |
|-[1] |
obj#1d57
(Container) |
|-location |
obj#1d59
(Surface) |
|-contents |
[obj#1d55
(Food)] |
|-[1] |
obj#1d55 (Food) |
|-location |
obj#1d59
(Surface) |
|-contents |
[] |
Tray,
bottle of milk, and milk are each cloned. The containment relationships between
the cloned milk, cloned bottle, and cloned tray paralleling that of the milk, bottle
of milk, and tray. You can take the bottle off the original tray and smash it
if you wish, or put it on the cloned tray. The two objects are independent of
one another.
Both the tray and the cloned
tray have the same location.
This file is part of the TADS 3
Proteus Library Extension
Copyright ©
2001-2004 Kevin Forchione.