Version 8 of oo::copy

Updated 2014-06-26 01:27:28 by pooryorick

oo::copy , a built-in Tcl command, creates a duplicate of a TclOO object.

Documentation

official reference

Synopsis

oo::copy sourceObject ?targetObject?

Description

oo::copy duplicates structure of an object and then calls an internal method of the created object, <cloned>, with the source object as an argument, which sets up any advanced properties of the created object based on the source object. The default implementation of that method in the oo::object class copies procedures and variables from the source object's namespace, but does not copy any traces or commands implemented in C.

Objects can potentially refuse to be duplicated, generating an error instead. Generating an error from the <cloned> method counts as refusal.

Wrapper That Respects Imported Procedures

oo::object <cloned> copies aliased procedures in the origin namespace over to the new namespace as native procedures. The following drop-in replacement changes that behaviour so that imported procedures are imported procedures in the new namespace as well. The code below is not necessarily recommended, as overriding <cloned> in a subclass is the recommended way of getting this behaviour.

rename copy oocopy
proc copy {sourceObject args} {
    set from [uplevel [list namespace which $sourceObject]]
    set fromns [info object namespace $from]
    if {[string range $fromns end-1 end] eq {::}} {
        set fromns [string range $fromns 0 end-2]
    }
    set to [uplevel [list [namespace current]::oocopy $from {*}$args]]
    set tons [info object namespace $to]
    foreach proc [info procs ${tons}::*] {
        set tail [namespace tail $proc]
        if {[namespace origin ${fromns}::$tail] ne "${fromns}::$tail"} {
            #For imported procedures ::oo::copy doesn't import the procedure
            #but creates an entirely new equivalent procedure in the new
            #namespace. This is probably not what's desired.  Delete the proc
            #that oo::copy made so that copycommands can just make an
            #equivalent import
            rename $proc {}
        }
    }
    copycommands $fromns $tons my
    return $to
}