Polymorphic copy: Difference between revisions

Added FreeBASIC
(Updated to work with Nim 1.4: replaced TObject with RootObj; added {.base.} on method "speak" for type T. Minor changes in text.)
(Added FreeBASIC)
 
(6 intermediate revisions by 5 users not shown)
Line 4:
 
It is trivial to copy an object if its type is known:
<langsyntaxhighlight lang="c">int x;
int y = x;</langsyntaxhighlight>
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 17:
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Test_Polymorphic_Copy is
Line 69:
Put_Line ("Cloned " & Object_3.all.Name);
Put_Line ("Cloned " & Object_4.all.Name);
end Test_Polymorphic_Copy;</langsyntaxhighlight>
The procedure Copier does not know the specific type of its argument.
Nevertheless it creates an object Duplicate of exactly same type.
Line 82:
=={{header|Aikido}}==
Aikido has a native <code>clone</code> function that creates a (deep or shallow) clone of any variable of any type.
<langsyntaxhighlight lang="aikido">
class T {
public function print {
Line 107:
scopy.print()
 
</syntaxhighlight>
</lang>
{{out}}
before copy
Line 120:
that are procedures. The following shows how the task can be accomplished by using structre instances with
different values of the procedures.
<langsyntaxhighlight lang="algol68">BEGIN
# Algol 68 doesn't have classes and inheritence as such, however structures #
# can contain procedures and different instances of a structure can have #
Line 170:
PRINT z1; print( ( newline ) );
PRINT z2; print( ( newline ) )
END</langsyntaxhighlight>
{{out}}
<pre>
Line 186:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> INSTALL @lib$ + "CLASSLIB"
REM Create parent class T:
Line 213:
result% = FN(mycopy.retval)(RunTimeSize%)
PRINT result%
END</langsyntaxhighlight>
{{out}}
<pre>
Line 225:
The code in "main" would also be a separate source file which would include Dog.h and Ferret.h header files (which would thems elves include the BaseObj.h header file.)
A better example of object oriented support in 'C' can be found in the source for the XtIntrinsics library of X11.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 426:
ObjDestroy(o1);
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
 
class T
Line 467:
Console.WriteLine(clone.Name());
}
}</langsyntaxhighlight>
{{out}}
<syntaxhighlight lang="text">S
S</langsyntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
 
class T
Line 522:
X copy = original; // copy it,
copy.identify_member(); // and check what type of member it contains
}</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Line 528:
With structures, <code>[http://www.lispworks.com/documentation/HyperSpec/Body/f_cp_stu.htm copy-structure]</code> performs the right kind of copy. The object and its copy are compared under <code>eq</code>, <code>eql</code>, <code>equal</code>, and <code>equalp</code> to demonstrate that "The objective is to create an exact copy of such polymorphic object (not to create a reference, nor a pointer to)."
 
<langsyntaxhighlight lang="lisp">(defstruct super foo)
 
(defstruct (sub (:include super)) bar)
Line 539:
(defmethod frob ((sub sub))
(format t "~&Sub has foo = ~w, bar = ~w."
(sub-foo sub) (sub-bar sub)))</langsyntaxhighlight>
 
<pre>> (let* ((sub1 (make-sub :foo 'foo :bar 'bar))
Line 557:
The same technique works for <code>[http://www.lispworks.com/documentation/HyperSpec/Body/t_seq.htm sequence]</code> and its subclasses (e.g., <code>[http://www.lispworks.com/documentation/HyperSpec/Body/t_string.htm string]</code>, <code>[http://www.lispworks.com/documentation/HyperSpec/Body/t_seq.htm list]</code>) when <code>[http://www.lispworks.com/documentation/HyperSpec/Body/f_cp_seq.htm copy-seq]</code> is used rather than <code>copy-structure</code>.
 
<langsyntaxhighlight lang="lisp">(defmethod frob ((sequence sequence))
(format t "~&sequence has ~w elements" (length sequence)))
 
(defmethod frob ((string string))
(format t "~&the string has ~w elements" (length string)))</langsyntaxhighlight>
 
<pre>> (let* ((hw1 "hello world")
Line 578:
 
If we assume there are no data members, this will be quite short and simple:
<langsyntaxhighlight lang="d">class T {
override string toString() { return "I'm the instance of T"; }
T duplicate() { return new T; }
Line 596:
writeln(orig);
writeln(copy);
}</langsyntaxhighlight>
{{out}}
<pre>I'm the instance of S
Line 603:
However this doesn't happen often in reality. If we want to copy data fields we should have something like copy constructor, that will
do the deep copy.
<langsyntaxhighlight lang="d">class T {
this(T t = null) {} // Constructor that will be used for copying.
 
Line 648:
orig.writeln;
copy.writeln; // Should have 'X' at the beginning.
}</langsyntaxhighlight>
{{out}}
<pre>I'm the instance of S p: Y23
Line 655:
=={{header|Delphi}}==
{{trans|C#}}
<langsyntaxhighlight lang="delphi">program PolymorphicCopy;
 
type
Line 687:
begin
Main;
end.</langsyntaxhighlight>
{{out}}
<syntaxhighlight lang="text">S
S</langsyntaxhighlight>
 
=={{header|E}}==
Line 696:
In E, a generic copy for all objects can be built out of the serialization facility, by connecting an object recognizer to an object builder without even using any intermediate serialized form:
 
<langsyntaxhighlight lang="e">def deSubgraphKit := <elib:serial.deSubgraphKit>
 
def copy(object) {
return deSubgraphKit.recognize(object, deSubgraphKit.makeBuilder())
}</langsyntaxhighlight>
 
Since E does not have any static dispatch, this cannot be non-polymorphic without also being non-generic.
Line 706:
An example showing that it does indeed make copies follows. (For the task description, let <var>S</var> be the type of all serializable E objects, <var>T</var> be the <code>[http://wiki.erights.org/wiki/FlexList FlexList]</code> type (result of <code>diverge</code>), and the overriden method be <code> [http://wiki.erights.org/wiki/FlexList#push/1 push]</code>.
 
<langsyntaxhighlight lang="e">? def a := [1].diverge()
# value: [1].diverge()
 
Line 717:
 
? b
# value: [1, 2].diverge()</langsyntaxhighlight>
 
See also: [[Deepcopy#E]]
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
(lib 'types)
(lib 'struct)
Line 747:
(K "string-inside") ;; trying to put a string in the container box
😡 error: T : type-check failure : string-inside → 'K:box'
</syntaxhighlight>
</lang>
 
=={{header|Elena}}==
ELENA 4.x :
<langsyntaxhighlight lang="elena">import extensions;
class T
Line 774:
console.printLine(original.Name);
console.printLine(clone.Name)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 784:
.NET objects have a protected method <code>MemberwiseClone</code>. This method creates a shallow copy of an object. Value type members are copied, i.e. not shared between clones. Reference type members, on the other hand, will reference the same objects after cloning.
 
<langsyntaxhighlight lang="fsharp">type T() =
// expose protected MemberwiseClone method (and downcast the result)
member x.Clone() = x.MemberwiseClone() :?> T
Line 797:
let s = new S()
let s2 = s.Clone() // the static type of s2 is T, but it "points" to an S
s2.Print() // prints "I'm an S!"</langsyntaxhighlight>
 
=={{header|Factor}}==
Line 804:
 
Pasting the following in a repl:
<langsyntaxhighlight lang="factor">USING: classes kernel prettyprint serialize ;
TUPLE: A ;
TUPLE: C < A ;
Line 811:
C new
[ clone ]
[ serial-clone ] bi [ class . ] bi@</langsyntaxhighlight>
{{out}}
C
Line 820:
{{trans|Aikido}}
There are numerous, mutually incompatible object oriented frameworks for Forth. This one works with the FOOS preprocessor extension of [[4tH]].
<langsyntaxhighlight lang="forth">include lib/memcell.4th
include 4pp/lib/foos.4pp
( a1 -- a2)
Line 855:
." after copy" cr
tcopy => print \ use "print" methods
scopy => print</langsyntaxhighlight>
 
 
Line 862:
Needs the FMS-SI (single inheritance) library code located here:
http://soton.mpeforth.com/flag/fms/index.html
<langsyntaxhighlight lang="forth">include FMS-SI.f
 
:class T
Line 887:
 
obj-t print-container \ class is S
</syntaxhighlight>
</lang>
 
=={{header|Fortran}}==
Tested with GNU gfortran 5.2.1 and INTEL ifort 16.
<syntaxhighlight lang="fortran">
<lang Fortran>
!-----------------------------------------------------------------------
!Module polymorphic_copy_example_module
Line 958:
 
end program test
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
FreeBASIC does not support object-oriented programming and polymorphy. However, you can simulate it using user-defined types and procedure pointers.
<syntaxhighlight lang="vbnet">Type T
method As Sub(pthis As T Ptr)
End Type
 
Type S Extends T
dato As Integer
End Type
 
Sub TMethod(pthis As T Ptr)
Print "T method"
End Sub
 
Sub SMethod(pthis As S Ptr)
Print "S method, dato = "; pthis->dato
End Sub
 
Sub CallMethod(pthis As T Ptr)
pthis->method(pthis)
End Sub
 
Dim As T tt
tt.method = @TMethod
 
Dim As S ss
ss.method = @SMethod
ss.dato = 123
 
Sleep</syntaxhighlight>
{{out}}
<pre>T method
S method, dato = 123</pre>
 
=={{header|Go}}==
Line 974 ⟶ 1,008:
You can see in the output that interface values of type r access t's identify method.
Values of type s would as well, except s has it's own identify method which takes precedence.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,057 ⟶ 1,091:
fmt.Println("i2c:", i2c, "/", i2c.identify(), "/", reflect.TypeOf(i2c))
fmt.Println("i3c:", i3c, "/", i3c.identify(), "/", reflect.TypeOf(i3c))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,084 ⟶ 1,118:
{{trans|Java}} (more or less)
Solution:
<langsyntaxhighlight lang="groovy">class T implements Cloneable {
String property
String name() { 'T' }
Line 1,097 ⟶ 1,131:
class S extends T {
@Override String name() { 'S' }
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang="groovy">T obj1 = new T(property: 'whatever')
S obj2 = new S(property: 'meh')
 
Line 1,113 ⟶ 1,147:
 
println "objA:: name: ${objA.name()}, property: ${objA.property}"
println "objB:: name: ${objB.name()}, property: ${objB.property}"</langsyntaxhighlight>
 
{{out}}
Line 1,126 ⟶ 1,160:
The deepcopy procedure is identical in both languages.
 
<langsyntaxhighlight lang="unicon">class T()
method a(); write("This is T's a"); end
end
Line 1,161 ⟶ 1,195:
}
return .cache[A]
end</langsyntaxhighlight>
 
Sample run:
Line 1,187 ⟶ 1,221:
If this pattern is followed, the calls will eventually pass all the way up to <code>Object</code>'s <code>clone()</code> method, which performs a polymorphic copy.
If you do not follow this pattern, and simply use a constructor, like <code>new T()</code>, then the copy won't be polymorphic.
<langsyntaxhighlight lang="java">class T implements Cloneable {
public String name() { return "T"; }
public T copy() {
Line 1,210 ⟶ 1,244:
System.out.println(copier(obj2).name()); // prints "S"
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
Copied from [http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone here]:
<langsyntaxhighlight lang="javascript">function clone(obj){
if (obj == null || typeof(obj) != 'object')
return obj;
Line 1,222 ⟶ 1,256:
temp[key] = clone(obj[key]);
return temp;
}</langsyntaxhighlight>
 
=={{header|Julia}}==
To perform as required in the exercise, mutable structs must be used to keep the deepcopy
procedure from being optimized away as a mere reference to the first struct.
<langsyntaxhighlight lang="julia">
abstract type Jewel end
 
Line 1,266 ⟶ 1,300:
 
testtypecopy()
</langsyntaxhighlight>{{output}} <pre>
a is a Jewel? true
b is a Jewel? true
Line 1,281 ⟶ 1,315:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
open class Animal(val name: String, var age: Int) {
Line 1,301 ⟶ 1,335:
println("Dog 'b' = $b") // ditto
println("Dog 'a' is ${if (a === b) "" else "not"} the same object as Dog 'b'")
}</langsyntaxhighlight>
 
{{out}}
Line 1,309 ⟶ 1,343:
Dog 'a' is not the same object as Dog 'b'
</pre>
 
=={{header|Lua}}==
Lua does not have any formal notion of OOP principles, however there are numerous ways to build work-alikes. The basic data type for building OOP-like systems is the <code>table</code>, which are easily copied (a shallow copy suffices for this task), and easily assigned (dynamically typed). The "prototype approach" (rather than the "metamethod approach") to OOP-like seems to better illustrate the task, so here such a system is built incrementally. One method will be overridden (per task), and one inherited (stretch), to better demonstrate that part of the original copy still remains while another part was modified:
<syntaxhighlight lang="lua">T = { name=function(s) return "T" end, tostring=function(s) return "I am a "..s:name() end }
 
function clone(s) local t={} for k,v in pairs(s) do t[k]=v end return t end
S1 = clone(T) S1.name=function(s) return "S1" end
 
function merge(s,t) for k,v in pairs(t) do s[k]=v end return s end
S2 = merge(clone(T), {name=function(s) return "S2" end})
 
function prototype(base,mixin) return merge(merge(clone(base),mixin),{prototype=base}) end
S3 = prototype(T, {name=function(s) return "S3" end})
 
print("T : "..T:tostring())
print("S1: " ..S1:tostring())
print("S2: " ..S2:tostring())
print("S3: " ..S3:tostring())
print("S3's parent: "..S3.prototype:tostring())</syntaxhighlight>
{{out}}
<pre>T : I am a T
S1: I am a S1
S2: I am a S2
S3: I am a S3
S3's parent: I am a T</pre>
 
=={{header|MiniScript}}==
<langsyntaxhighlight MiniScriptlang="miniscript">T = {}
T.foo = function()
return "This is an instance of T"
Line 1,332 ⟶ 1,391:
copy.bar = 2
print "instance.bar: " + instance.bar
print "copy.bar: " + copy.bar</langsyntaxhighlight>
{{out}}
<pre>instance.foo: This is an S for sure
Line 1,341 ⟶ 1,400:
=={{header|NetRexx}}==
{{trans|Java}}
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref savelog symbols binary
 
Line 1,379 ⟶ 1,438:
method name returns String
return S.class.getSimpleName
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">type
T = ref object of RootObj
myValue: string
Line 1,418 ⟶ 1,477:
u.myValue = "Yellow"
u.speak
b.speak</langsyntaxhighlight>
{{out}}
<pre>creating initial objects of types S1, S2, and T.
Line 1,445 ⟶ 1,504:
If your parent class already implements <code>NSCopying</code>, and you wish to customize the copying of your class's fields, then you should get a copy from your parent object's <code>copyWithZone:</code> method, and then perform custom initialization on the copy.
 
<langsyntaxhighlight lang="objc">@interface T : NSObject
- (void)identify;
@end
Line 1,482 ⟶ 1,541:
}
return 0;
}</langsyntaxhighlight>
 
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).
Line 1,489 ⟶ 1,548:
=={{header|OCaml}}==
I decided not to use classes and inheritance here because structural subtyping is more natural in OCaml. Oo.copy is polymorphic over all object types.
<langsyntaxhighlight lang="ocaml">let obj1 =
object
method name = "T"
Line 1,501 ⟶ 1,560:
let () =
print_endline (Oo.copy obj1)#name; (* prints "T" *)
print_endline (Oo.copy obj2)#name; (* prints "S" *)</langsyntaxhighlight>
 
=={{header|ooRexx}}==
All ooRexx objects have a copy method inherited from the object class that performs a shallow copy of the object state.
<syntaxhighlight lang="oorexx">
<lang ooRexx>
s = .s~new
s2 = s~copy -- makes a copy of the first
Line 1,518 ⟶ 1,577:
::method name
return "S"
</syntaxhighlight>
</lang>
 
=={{header|OxygenBasic}}==
<langsyntaxhighlight lang="oxygenbasic">
'======
class T
Line 1,559 ⟶ 1,618:
 
del objA : del objB
</syntaxhighlight>
</lang>
 
=={{header|Oz}}==
We need to derive from the class <code>ObjectSupport.reflect</code> in order to have a <code>clone</code> method.
<langsyntaxhighlight lang="oz">declare
class T from ObjectSupport.reflect
meth init
Line 1,603 ⟶ 1,662:
{Obj setA(13)}
{Copy setA(14)}
{Obj getA($)} \= {Copy getA($)} = true</langsyntaxhighlight>
 
Oz is not a pure object-oriented language. In fact, most values are not objects.
Line 1,610 ⟶ 1,669:
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">package T;
sub new {
my $cls = shift;
Line 1,662 ⟶ 1,721:
$x->set_data('totally different');
print "\$x is: ";
$x->manifest;</langsyntaxhighlight>
 
=={{header|Phix}}==
Line 1,669 ⟶ 1,728:
 
For this demonstration (not that this really proves much), our types T and S (overkill really) are just going to contain a string name and a method (routine_id).
<lang Phix>enum NAME, METHOD
 
<!--<syntaxhighlight lang="phix">(phixonline)-->
procedure me_t()
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
puts(1,"I is a T\n")
<span style="color: #008080;">enum</span> <span style="color: #000000;">NAME</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">METHOD</span>
end procedure
constant r_t = routine_id("me_t")
<span style="color: #008080;">procedure</span> <span style="color: #000000;">me_t</span><span style="color: #0000FF;">()</span>
 
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I is a T\n"</span><span style="color: #0000FF;">)</span>
procedure me_s()
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
puts(1,"I is an S\n")
end procedure
<span style="color: #008080;">procedure</span> <span style="color: #000000;">me_s</span><span style="color: #0000FF;">()</span>
constant r_s = routine_id("me_s")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I is an S\n"</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
type T(object o)
-- as o[METHOD] can be overidden, don't verify it!
<span style="color: #008080;">type</span> <span style="color: #000000;">T</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">)</span>
return sequence(o) and length(o)=2 and string(o[NAME]) and integer(o[METHOD])
<span style="color: #000080;font-style:italic;">-- as o[METHOD] can be overidden, don't verify it (as in test for me_t)!</span>
end type
<span style="color: #008080;">return</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span> <span style="color: #008080;">and</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">NAME</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">and</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">[</span><span style="color: #000000;">METHOD</span><span style="color: #0000FF;">])</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
type S(T t)
return t[METHOD] = r_s
<span style="color: #008080;">type</span> <span style="color: #000000;">S</span><span style="color: #0000FF;">(</span><span style="color: #000000;">T</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
end type
<span style="color: #008080;">return</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">METHOD</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">me_s</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
S this = {"S",r_s}
T that = {"T",r_t}
<span style="color: #000000;">S</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"S"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">me_s</span><span style="color: #0000FF;">}</span>
<span style="color: #000000;">T</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"T"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">me_t</span><span style="color: #0000FF;">}</span>
<span style="color: #7060A8;">call_proc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">METHOD</span><span style="color: #0000FF;">],{})</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span>
<span style="color: #7060A8;">call_proc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">METHOD</span><span style="color: #0000FF;">],{})</span>
<!--</syntaxhighlight>-->
 
call_proc(that[METHOD],{})
that = this
call_proc(that[METHOD],{})</lang>
{{out}}
<pre>
Line 1,705 ⟶ 1,767:
Not recommended or formally supported, but these sort of low-level things are perfectly possible.<br>
Note the result from get_struct_fields() is not documented and liable to change between releases.<br>
The deep_copydeep_copy_class() routine also shows how to break privacy on fetch/set of private fields by faking the context (name).
<lang Phix>include builtins/structs.e
 
<!--<syntaxhighlight lang="phix">-->
function deep_copy(class c)
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (no class under p2js, and certainly not the low-level stuff)</span>
string name = get_struct_name(c)
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #000000;">structs</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
class res = new(name)
sequence fields = get_struct_fields(c)
<span style="color: #008080;">function</span> <span style="color: #000000;">deep_copy_class</span><span style="color: #0000FF;">(</span><span style="color: #008080;">class</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
for i=1 to length(fields) do
<span style="color: #004080;">string</span> <span style="color: #000000;">name</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_struct_name</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
string field = fields[i][1]
<span style="color: #008080;">class</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new</span><span style="color: #0000FF;">(</span><span style="color: #000000;">name</span><span style="color: #0000FF;">)</span>
store_field(res,field,fetch_field(c,field,name),name)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">fields</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_struct_fields</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fields</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
return res
<span style="color: #004080;">string</span> <span style="color: #000000;">field</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fields</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
end function
<span style="color: #000000;">store_field</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">field</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fetch_field</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">field</span><span style="color: #0000FF;">,</span><span style="color: #000000;">name</span><span style="color: #0000FF;">),</span><span style="color: #000000;">name</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
class T
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
private atom x
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
public atom y
procedure show()
<span style="color: #008080;">class</span> <span style="color: #000000;">T</span>
printf(1,"This is T%d/%d\n",{x,y})
<span style="color: #008080;">private</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">x</span>
end procedure
<span style="color: #008080;">public</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">y</span>
end class
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"This is T%d/%d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">class</span>
<span style="color: #000000;">T</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}),</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">deep_copy_class</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">.</span><span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
 
T t = new({1,2}),
s = deep_copy(t)
s.y = 3
t.show()
s.show()</lang>
{{out}}
<pre>
Line 1,739 ⟶ 1,806:
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php"><?php
class T {
function name() { return "T"; }
Line 1,754 ⟶ 1,821:
echo $obj3->name(), "\n"; // prints "T"
echo $obj4->name(), "\n"; // prints "S"
?></langsyntaxhighlight>
 
=={{header|PicoLisp}}==
Any object can be copied by transferring the value and the property list.
If we create an object 'A':
<langsyntaxhighlight PicoLisplang="picolisp">: (setq A (new '(+Cls1 +Cls2) 'attr1 123 'attr2 "def" 'attr3 (4 2 0) 'attr4 T))
-> $385603635
 
Line 1,768 ⟶ 1,835:
attr2 "def"
attr1 123
-> $385603635</langsyntaxhighlight>
Then we can easily copy it to a new object 'B':
<langsyntaxhighlight PicoLisplang="picolisp">(putl (setq B (new (val A))) (getl A))</langsyntaxhighlight>
Inspecting 'B':
<langsyntaxhighlight PicoLisplang="picolisp">: (show B)
$385346595 (+Cls1 +Cls2)
attr1 123
Line 1,778 ⟶ 1,845:
attr3 (4 2 0)
attr4
-> $385346595</langsyntaxhighlight>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">import copy
 
class T:
Line 1,834 ⟶ 1,901:
u.myValue = "Yellow"
u.speak()
b.speak()</langsyntaxhighlight>
{{out}}
<pre>
Line 1,863 ⟶ 1,930:
Under Python this would best be done with the ''pickle'' or ''cPickle'' standard modules.
 
<langsyntaxhighlight lang="python">import cPickle as pickle
 
source = {'a': [1, 2.0, 3, 4+6j],
Line 1,869 ⟶ 1,936:
'c': None}
 
target = pickle.loads(pickle.dumps(source))</langsyntaxhighlight>
 
In this example we use the ''cPickle'' module which is an implementation of the pickle features coded in C for optimal performance.
Line 1,879 ⟶ 1,946:
For the simplest cases one can use simple Python introspection to copy simple objects:
 
<langsyntaxhighlight 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 1,886 ⟶ 1,953:
target = source[:]
else: # Following is not recommended. (see below).
target = source</langsyntaxhighlight>
 
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."
Line 1,899 ⟶ 1,966:
===Using prefab structures===
This method is useful only for prefab structures.
<langsyntaxhighlight Racketlang="racket">#lang racket/base
 
(define (copy-prefab-struct str)
Line 1,916 ⟶ 1,983:
[copied (copy-prefab-struct original)])
(displayln copied)
(displayln (eq? original copied)))</langsyntaxhighlight>
{{out}}
<pre>#s(struct:point 0 0)
Line 1,928 ⟶ 1,995:
 
It’s also possible to copy other structures using generics or structure-type-properties to implement a “magic”-like generic method.
<langsyntaxhighlight Racketlang="racket">#lang racket/base
 
(define (copy-struct str)
Line 1,946 ⟶ 2,013:
[copied (copy-struct original)])
(displayln copied)
(displayln (eq? original copied)))</langsyntaxhighlight>
{{out}}
<pre>#s(struct:point 0 0)
Line 1,956 ⟶ 2,023:
===Using classes===
There is no build-in clone method, so the class (or the interface) must implement it.
<langsyntaxhighlight Racketlang="racket">;#lang racket
 
(define point%
Line 1,971 ⟶ 2,038:
(init-field color)
(define/override (clone) (new this% [x x] [y y] [color color]))
(define/override (to-list) (list this% x y color))))</langsyntaxhighlight>
{{out}}
<pre>(#<class:point%> 0 0)
Line 1,981 ⟶ 2,048:
(formerly Perl 6)
{{works with|Rakudo|2020.08.1}}
<syntaxhighlight lang="raku" perl6line>my Cool $x = 22/7 but role Fink { method brag { say "I'm a cool {self.WHAT.raku}!" }}
my Cool $y = $x.clone;
$y.brag;</langsyntaxhighlight>
{{out}}
<pre>I'm a cool Rat+{Fink}!</pre>
Line 1,990 ⟶ 2,057:
In the REXX language, every variable is a string &nbsp; (whether or not they contain characters or numerals).
<br>However, a variables' type (by REXX's definition) can be determined/inferred from it's attributes (datatypes).
<langsyntaxhighlight lang="rexx">/*REXX program to copy (polymorphically) one variable's value into another variable. */
b= 'old value.'
a= 123.45
Line 1,996 ⟶ 2,063:
if a==b then say "copy did work."
else say "copy didn't work." /*didn't work, maybe ran out of storage*/
/*stick a fork in it, we're all done. */</langsyntaxhighlight>
Programming note: &nbsp; Most REXXes will raise a syntax error if an assignment (copy) fails, but it's not guaranteed to do so.<br><br>
 
Line 2,002 ⟶ 2,069:
All Ruby objects inherit two methods for copying themselves: "clone" and "dup".
I don't really understand the difference between them.
<langsyntaxhighlight lang="ruby">class T
def name
"T"
Line 2,017 ⟶ 2,084:
obj2 = S.new
puts obj1.dup.name # prints "T"
puts obj2.dup.name # prints "S"</langsyntaxhighlight>
 
=={{header|Scala}}==
<syntaxhighlight lang="text">object PolymorphicCopy {
 
def main(args: Array[String]) {
Line 2,040 ⟶ 2,107:
}
 
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
''Object.dclone()'' makes a deep clone of any mutable object and returns it to the caller.
<langsyntaxhighlight lang="ruby">class T(value) {
method display {
say value;
Line 2,065 ⟶ 2,132:
obj1.display; # prints "foo"
obj2.display; # prints "bar"
obj3.display; # prints "S"</langsyntaxhighlight>
 
=={{header|Slate}}==
Line 2,073 ⟶ 2,140:
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.
 
<langsyntaxhighlight lang="slate">define: #T &parents: {Cloneable}.
 
define: #S &parents: {Cloneable}.
Line 2,081 ⟶ 2,148:
 
obj1 printName.
obj2 printName.</langsyntaxhighlight>
 
=={{header|Swift}}==
<langsyntaxhighlight lang="swift">class T {
required init() { } // constructor used in polymorphic initialization must be "required"
func identify() {
Line 2,107 ⟶ 2,174:
let another : T = original.copy()
println(original === another) // prints "false" (i.e. they are different objects)
another.identify() // prints "I am an S"</langsyntaxhighlight>
 
=={{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:
<syntaxhighlight lang ="tcl">set varCopy $varOriginal</langsyntaxhighlight>
With objects, slightly more work is required because they are normally passed around by name/reference.
<br>
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
<langsyntaxhighlight lang="tcl">oo::class create CanClone {
method clone {{name {}}} {
# Make a bare, optionally named, copy of the object
Line 2,157 ⟶ 2,224:
$obj2 rename "Hocus Pocus"
$obj2 print
$obj1 print</langsyntaxhighlight>
{{out}} (object names might vary if you run it):
<pre>
Line 2,165 ⟶ 2,232:
this is Abracadabra in ::oo::Obj5, stepped 2 times
</pre>
 
=={{header|TXR}}==
 
TXR Lisp has a <code>copy</code> function that produces copies of objects of all sorts.
Structures are shallowly copied; the <code>copy-struct</code> function is used when the
argument is a structure. Our polymorphic object can use <code>copy</code> to make a shallow copy of itself which shares a reference to the contained object. Then break the reference by calling <code>copy</code> on the object contained in the copy.
 
<syntaxhighlight lang="txrlisp">(defstruct base ()
(:method identify (self) (put-line "base")))
 
(defstruct derived (base)
(:method identify (self) (put-line "derived")))
 
(defstruct poly ()
obj
 
(:method deep-copy (self)
(let ((c (copy self))) ;; make copy of s
(upd c.obj copy) ;; copy self's obj
c))) ;; return c
 
;; Test
 
(let* ((b (new base))
(d (new derived))
(p (new poly obj d)))
b.(identify) ;; prints base
d.(identify) ;; prints derived
 
(let ((c p.(deep-copy)))
p.obj.(identify) ;; prints derived
(prinl (eq p.obj c.obj)))) ;; prints nil: c.obj is not a ref to p.obj</syntaxhighlight>
 
{{out}}
 
<pre>base
derived
derived
nil</pre>
 
=={{header|Wren}}==
Line 2,173 ⟶ 2,279:
 
There is no built in 'copy' method - you need to write your own for any class that needs it.
<langsyntaxhighlight ecmascriptlang="wren">class Animal {
construct new(name, age) {
_name = name
Line 2,205 ⟶ 2,311:
System.print("Dog 'a' -> %(a)") // implicitly calls a's toString method
System.print("Dog 'b' -> %(b)") // ditto
System.print("Dog 'a' is %((Object.same(a, b)) ? "" : "not") the same object as Dog 'b'")</langsyntaxhighlight>
 
{{out}}
2,130

edits