- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables
Class ::nx::CopyHandler
::nx::CopyHandler create ... \
[ -dest (default "") ] \
[ -objLength objLength ] \
[ -targetList (default "") ]
Class Relations
::nx::Class create ::nx::CopyHandler \ -superclass ::nx::ObjectMethods (to be applied on instances)
copy (scripted)
set :objLength [string length $obj] set :dest $dest :makeTargetList $obj :copyTargetscopyTargets (scripted)
set objs {} array set cmdMap {alias alias forward forward method create setter setter} foreach origin [set :targetList] { set dest [:getDest $origin] if {[::nsf::object::exists $origin]} { if {$dest eq ""} { #set obj [[$origin info class] new -noinit] set obj [::nsf::object::alloc [$origin info class] ""] #nsf::object::property $obj initialized 1 set dest [set :dest $obj] } else { # # Slot container are handled separately, since # ::nx::slotObj does already the right thing. We have just # to copy the variables (XOTcl keeps the parameter # definitions there). # if {[::nsf::object::property $origin slotcontainer]} { ::nx::slotObj -container [namespace tail $origin] [namespace qualifiers $dest] ::nsf::nscopyvars $origin $dest continue } else { # # create an object without calling init # #set obj [[$origin info class] create $dest -noinit] set obj [::nsf::object::alloc [$origin info class] $dest] #nsf::object::property $obj initialized 1 #puts stderr "COPY obj=<$obj>" } } # copy class information if {[::nsf::is class $origin]} { # obj is a class, copy class specific information ::nsf::relation::set $obj superclass [$origin ::nsf::methods::class::info::superclass] ::nsf::method::assertion $obj class-invar [::nsf::method::assertion $origin class-invar] ::nsf::relation::set $obj class-filter [::nsf::relation::get $origin class-filter] ::nsf::relation::set $obj class-mixin [::nsf::relation::get $origin class-mixin] ::nsf::nscopyvars ::nsf::classes$origin ::nsf::classes$dest foreach m [$origin ::nsf::methods::class::info::methods -path -callprotection all] { set rest [lassign [$origin ::nsf::methods::class::info::method definition $m] . protection what .] # remove -returns from reported definitions set p [lsearch -exact $rest -returns] if {$p > -1} {set rest [lreplace $rest $p $p+1]} set pathData [$obj eval [list :__resolve_method_path $m]] set object [dict get $pathData object] # # Create a copy of the instance method and set the method # properties with separate primitive commands. # set r [::nsf::method::$cmdMap($what) $object [dict get $pathData methodName] {*}$rest] ::nsf::method::property $object $r returns [$origin ::nsf::methods::class::info::method returns $m] ::nsf::method::property $object $r call-protected [::nsf::method::property $origin $m call-protected] ::nsf::method::property $object $r call-private [::nsf::method::property $origin $m call-private] } } # copy object -> might be a class obj ::nsf::object::property $obj keepcallerself [::nsf::object::property $origin keepcallerself] ::nsf::object::property $obj perobjectdispatch [::nsf::object::property $origin perobjectdispatch] ::nsf::object::property $obj hasperobjectslots [::nsf::object::property $origin hasperobjectslots] ::nsf::method::assertion $obj check [::nsf::method::assertion $origin check] ::nsf::method::assertion $obj object-invar [::nsf::method::assertion $origin object-invar] ::nsf::relation::set $obj object-filter [::nsf::relation::get $origin object-filter] ::nsf::relation::set $obj object-mixin [::nsf::relation::get $origin object-mixin] # reused in XOTcl, no "require namespace" there, so use nsf primitiva if {[::nsf::directdispatch $origin ::nsf::methods::object::info::hasnamespace]} { ::nsf::directdispatch $obj ::nsf::methods::object::requirenamespace } } else { namespace eval $dest {} } lappend objs $obj ::nsf::nscopyvars $origin $dest foreach m [$origin ::nsf::methods::object::info::methods -path -callprotection all] { set rest [lassign [$origin ::nsf::methods::object::info::method definition $m] . protection . what .] # remove -returns from reported definitions set p [lsearch -exact $rest -returns]; if {$p > -1} {set rest [lreplace $rest $p $p+1]} set pathData [$obj eval [list :__resolve_method_path -per-object $m]] set object [dict get $pathData object] # # Create a copy of the object method and set the method # properties with separate primitive commands. # set r [::nsf::method::$cmdMap($what) $object -per-object [dict get $pathData methodName] {*}$rest] ::nsf::method::property $object -per-object $r returns [$origin ::nsf::methods::object::info::method returns $m] ::nsf::method::property $object -per-object $r call-protected [::nsf::method::property $origin -per-object $m call-protected] ::nsf::method::property $object -per-object $r call-private [::nsf::method::property $origin -per-object $m call-private] } # # transfer the traces # foreach var [$origin info vars] { set cmds [::nsf::directdispatch $origin -frame object ::trace info variable $var] #puts stderr "COPY $var <$cmds>" if {$cmds ne ""} { foreach cmd $cmds { lassign $cmd op def #$origin trace remove variable $var $op $def set domain [lindex $def 0] if {$domain eq $origin} { set def [concat $dest [lrange $def 1 end]] } #puts stderr "COPY $var domain $domain [::nsf::object::exists $domain] && [$domain info has type ::nx::Slot]" #if {[::nsf::object::exists $domain] && [$domain info has type ::nx::Slot]} { # slot traces are handled already by the slot mechanism #continue #} # # handle the most common cases to replace $origin by $dest in trace command # if {[lindex $def 2] eq $origin} { set def [lreplace $def 2 2 $dest] } elseif {[lindex $def 0] eq $origin} { set def [lreplace $def 0 0 $dest] } ::nsf::directdispatch $dest -frame object ::trace add variable $var $op $def } } } } # # alter 'domain' and 'manager' in slot objects # foreach origin [set :targetList] { set dest [:getDest $origin] set slots [list] # # get class specific slots # if {[::nsf::is class $origin]} { set slots [$origin ::nsf::methods::class::info::slotobjects -type ::nx::Slot] } # # append object specific slots # foreach slot [$origin ::nsf::methods::object::info::slotobjects -type ::nx::Slot] { lappend slots $slot } #puts stderr "replacing domain and manager from <$origin> to <$dest> in slots <$slots>" foreach oldslot $slots { set container [expr {[$oldslot cget -per-object] ? "per-object-slot" : "slot"}] set newslot [::nx::slotObj -container $container $dest [namespace tail $oldslot]] if {[$oldslot cget -domain] eq $origin} {$newslot configure -domain $dest} if {[$oldslot cget -manager] eq $oldslot} {$newslot configure -manager $newslot} $newslot eval :init } } return [lindex $objs 0]dest (forward)
getDest (scripted)
if {${:dest} eq ""} { return "" } else { set tail [string range $origin [set :objLength] end] return ::[string trimleft [set :dest]$tail :] }makeTargetList (scripted)
if {[::nsf::is object,type=::nx::EnsembleObject $t]} { # # we do not copy ensemble objects, since method # introspection/recreation will care about these # return } lappend :targetList $t #puts stderr "COPY makeTargetList $t targetList '${:targetList}'" # if it is an object without namespace, it is a leaf if {[::nsf::object::exists $t]} { if {[::nsf::directdispatch $t ::nsf::methods::object::info::hasnamespace]} { # make target list from all children set children [$t info children] } else { # ok, no namespace -> no more children return } } # now append all namespaces that are in the obj, but that # are not objects foreach c [namespace children $t] { if {![::nsf::object::exists $c]} { lappend children [namespace children $t] } } # a namespace or an obj with namespace may have children # itself foreach c $children { :makeTargetList $c }objLength (forward)
targetList (forward)
- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables