Coyote's Guide to IDL Programming

Copying an IDL Object

QUESTION: I would like to make a copy of an instance of the self object from within an object method. But this code only copies the object reference (and is hence a reference to the same instance), not a separate instance of the object. Is there a way to make a second instance of the object that is defined exactly like the self object? In other words, a clone of the object?

   PRO My_Obj::Copy, out
   out = Replicate(self, 1)
   END

ANSWER: Although an object is implemented in IDL as a named structure, it is obviously a very different kind of thing and it is rather difficult to make a field by field copy of the fields that make up the structure. That is why the Replicate function fails.

Here is an example of an object method that can perform a field by field copy of the fields of a object into another object instance of the same object class. It takes advantage of the fact that you can create a structure from the class definition of the object.

   PRO My_Obj::Copy, out
   selfClass = Obj_Class(self)
   outClass = Obj_Class(out)
   IF selfClass NE outClass THEN BEGIN
	ok = Dialog_Message('Object classes not identical.')
       RETURN
   END
   ok = Execute('struct = {' + selfClass + '}')
   tags = N_Tags(struct)
   FOR j=0,tags-1 DO out.(j) = self.(j)
   END

Note that this copies only the top-level fields, and if the self structure contains pointers or other object references, that only the references are copied, not the data itself.

Since IDL 5.2, the Struct_Assign command in IDL can be used to copy object references in this field by field way. The code to do so would look like this, where the out object is an object reference of the same object class as self.

   PRO My_Obj::Copy, out
   selfClass = Obj_Class(self)
   outClass = Obj_Class(out)
   IF selfClass NE outClass THEN BEGIN
	ok = Dialog_Message('Object classes not identical.)
       RETURN
   END
   Struct_Assign, self, out
   END

There is one method that can create a "deep" copy of an object (meaning that the copied object is a true clone of the original object), but the method is extremely slow and can often not be used for that reason. The method requires that you SAVE the original object in an IDL save file, and then RESTORE it, which produces the clone.

Aside from being slow, the method has other inherent dangers. It is dependent on local disk space, requires permissions to write files, can run into security issues, et cetera. If you use it in an important program, you are almost guaranteed something will go wrong with it. But, aside from that, it works extremely well!

Here is a short object Clone method, written by Paul Schleger, that illustrates how it can be done.

   FUNCTION My_Obj::Clone, Object=object
   IF( NOT Keyword_Set(object) ) THEN object = self
   obj = object
   filename = 'clone.sav'
   Save, obj, Filename=filename
   obj = 0 ; This is the trick to get the restore to 'clone' what it saved
   Restore, filename
   File_Delete, filename, /Quiet
   RETURN, obj
   END

Google
 
Web Coyote's Guide to IDL Programming