Polymorphic copy: Difference between revisions

→‎{{header|Tcl}}: Implement an object cloning demonstration
m (whitespace)
(→‎{{header|Tcl}}: Implement an object cloning demonstration)
Line 518:
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 tcl>set varCopy $varOriginal</lang>
With objects, slightly more work is required because they are normally passed around by name/reference.
<br>
{{works with|Tcl|8.6}}
<lang tcl>oo::class create CanClone {
method clone {{name {}}} {
# Make a bare, optionally named, copy of the object
set new [oo::copy [self] {*}[expr {$name eq "" ? {} : [list $name]}]]
 
# Reproduce the basic variable state of the object
set newns [info object namespace $new]
foreach v [info object vars [self]] {
namespace upvar [namespace current] $v v1
namespace upvar $newns $v v2
if {[array exists v1]} {
array set v2 [array get v1]
} else {
set v2 $v1
}
}
# Other object state is possible like open file handles. Cloning that is
# properly left to subclasses, of course.
 
return $new
}
}
 
# Now a demonstration
oo::class create Example {
superclass CanClone
variable Count Name
constructor {name} {set Name $name;set Count 0}
method step {} {incr Count;return}
method print {} {puts "this is $Name in [self], stepped $Count times"}
method rename {newName} {set Name $newName}
}
set obj1 [Example new "Abracadabra"]
$obj1 step
$obj1 step
$obj1 print
set obj2 [$obj1 clone]
$obj2 step
$obj2 print
$obj2 rename "Hocus Pocus"
$obj2 print
$obj1 print</lang>
Which produces this output (object names might vary if you run it):
<pre>
this is Abracadabra in ::oo::Obj5, stepped 2 times
this is Abracadabra in ::oo::Obj6, stepped 3 times
this is Hocus Pocus in ::oo::Obj6, stepped 3 times
this is Abracadabra in ::oo::Obj5, stepped 2 times
</pre>
 
{{Omit From|ALGOL 68}} <!-- it isn't immediately obvious that ALGOL 68 is object oriented -->
Anonymous user