Simulation Clones

TADS 3 and Proteus provide several ways to “copy” an object. Each of these methods returns an object that that in some way incorporates the essence of the original, but each method has important differences.

 

·      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 with Using TADS Instances as Object Copies

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 Arnold dies, so does his “clone”, unless it overrides his state attributes.

 

Why Shallow Cloning Isn’t Always Enough

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.

 

Creating a Simulation Clone

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. All rights reserved.