Polymorphic copy: Difference between revisions

m
whitespace
(javascript)
m (whitespace)
Line 2:
 
It is trivial to copy an object if its type is known:
<lang c>int x;
int y = x;</lang>
int y = x;
</lang>
Here x is not polymorphic, so y is declared of same type (''int'') as x. But if the specific type of x were unknown, then y could not be declared of any specific type.
 
Line 11 ⟶ 9:
 
=={{header|Ada}}==
<lang ada>with Ada.Text_IO; use Ada.Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
 
procedure Test_Polymorphic_Copy is
Line 53 ⟶ 50:
Copier (Object_1);
Copier (Object_2);
end Test_Polymorphic_Copy;</lang>
</lang>
The procedure Copier does not know the specific type of its argument. Nevertheless it creates an object Duplicate of exactly same type. Sample output:
<pre>
Line 62 ⟶ 58:
 
=={{header|C++}}==
<lang cpp>#include <iostream>
#include <iostream>
 
class T
Line 112 ⟶ 107:
X copy = original; // copy it,
copy.identify_member(); // and check what type of member it contains
}</lang>
}
</lang>
 
=={{header|Common Lisp}}==
Line 170 ⟶ 164:
 
If we assume there are no data members, this will be quite short and simple:
<lang D>import tango.io.Stdout;
import tango.io.Stdout;
 
class T {
Line 192 ⟶ 185:
Stdout (orig).newline;
Stdout (copy).newline;
}</lang>
}
</lang>
 
Hovever this doesn't happen often in reality.
Line 199 ⟶ 191:
If we want to copy data fields we should have something like copy ctor, that will
do the deep copy.
<lang D>import tango.io.Stdout;
import tango.io.Stdout;
 
class T {
Line 242 ⟶ 233:
Stdout (orig).newline;
Stdout (copy).newline; // should have 'X' at the beginning
}</lang>
}
</lang>
 
=={{header|E}}==
Line 316 ⟶ 306:
Implementing copying can be done with the <code>NSCopyObject()</code> function for a simple byte-for-byte shallow copy of the object fields. Or you can do something more complicated like explicitly allocate a new object of a certain class (but then it won't really be polymorphic) and initialize it with your object's data. I am not really clear on the details of this.
 
<lang objc>@interface T : NSObject
@interface T : NSObject
{ }
- (void)identify;
Line 356 ⟶ 345:
[original release];
return 0;
}</lang>
}
</lang>
 
Analogously, there is a <code>mutableCopy</code> method to get a mutable copy of the current object (e.g. if you have an NSArray object and you want an NSMutableArray with the same contents). In this case it would have to implement the <code>mutableCopyWithZone:</code> method to specify how to copy.
Line 471 ⟶ 459:
In many cases the most portable and robust "copy" would be made by serializing the source object and then de-serializing it back into the target. Under Python this would best be done with the ''pickle'' or ''cPickle'' standard modules.
 
<lang python>import cPickle as pickle
import cPickle as pickle
 
source = {'a': [1, 2.0, 3, 4+6j],
Line 478 ⟶ 465:
'c': None}
 
target = pickle.loads(pickle.dumps(source))</lang>
</lang>
 
In this example we use the ''cPickle'' module which is an implementation of the pickle features coded in C for optimal performance. We import it as ''pickle'' since we intend to use only those features which are common to both implementations. (The pure Python implementation is retained for those who which to create their own classes derived therefrom). The ''dumps()'' and ''loads()'' methods dump the data structures to a string and load them from a string, respectively. (The more common use of ''pickle'' is to serialize the data out to a file or over a network connection using file-like ''.read()'' and ''.write()'' methods. For those we'd use the ''pickle.dump()'' and ''pickle.load()'' methods).
Line 485 ⟶ 471:
For the simplest cases one can use simple Python introspection to copy simple objects:
 
<lang python>target = source.__class__() # Create an object of the same type
<lang python>
target = source.__class__() # Create an object of the same type
if hasattr(source, 'items') and callable(source.items):
for key,value in source.items:
Line 493 ⟶ 478:
target = source[:]
else: # Following is not recommended. (see below).
target = source</lang>
</lang>
 
This example handles dictionaries (and anything that implements a sufficiently dictionary like interface to support the ''items()'' method along with the ''__setitem__()'' method. (statements of the form '''''x[y] = z''''' in Python are implicitly calling the ''__setitem__()'' method of the "x" object, passing it a key of "y" and a value of "z." Similarly this code tests if an item is a sequence (one can call the "len()" built-in function on it) and, if so, uses a slice assignment to perform a shallow copy. For any other type of object a simple binding is performed. Technically this last case will not "copy" anything ... it will create a new name binding to the object to which "source" was already a reference. The earlier binding of a "blank" instance of the source's __class__ will be replaced. So the trick of creating the blank object of the same type is only meaningful for the other types. In the cases of strings, integers and other numbers the objects themselves are immutable and the bindings are all dynamic (so the entire task is moot with respect to them).
Line 521 ⟶ 505:
All objects in Slate may be <tt>clone</tt>d unless they are clones of <tt>Oddball</tt> (like <tt>True</tt>, <tt>False</tt>, and <tt>Nil</tt>) or are word-size Integers (which are encoded as tagged pointer values). This is a shallow copy where no values held in the object's slots are replaced with copies. There is also a <tt>copy</tt> method which is universal and overridden to perform deep copies as appropriate - copying continues via recursion through slot values and should be modified on any type where equality (<tt>=</tt>) is overridden.
 
<lang slate>define: #T &parents: {Cloneable}.
define: #T &parents: {Cloneable}.
 
define: #S &parents: {Cloneable}.
Line 530 ⟶ 513:
 
obj1 printName.
obj2 printName.</lang>
 
</lang>
 
=={{header|Tcl}}==
Tcl values are logically immutable, and are passed around by reference with copies being taken as and when it is necessary to do so to maintain the immutable model. Hence an effective copy of any value is just:
<lang Tcltcl>set varCopy $varOriginal</lang>
 
{{Omit From|ALGOL 68}} <!-- it isn't immediately obvious that ALGOL 68 is object oriented -->
{{omit from|M4}}
Anonymous user