Wed Jul 19, 2006, CMcC: A quickie to serialise the variables in a sub-interpreter.
This has undoubtedly already been done, but I can't recall where it is.
nstree returns a flattened trees of all namespaces in the interp.
proc nstree {interp {prefix ""}} { set result {} foreach ns [$interp eval [list namespace children $prefix]] { lappend result $ns lappend result {*}[nstree $interp $ns] } return $result }
serialize returns a valid tcl command to recreate the variables in the interp.
proc serialize {interp} { $interp eval {unset -nocomplain errorCode; unset -nocomplain errorInfo} set result {} foreach v [$interp eval info globals] { if {[string match tcl* $v]} continue if {[$interp eval [list array exists $v]]} { lappend result [list array set $v [$interp eval [list array get $v]]] } else { lappend result [list set $v [$interp eval [list set $v]]] } } foreach ns [nstree $interp] { set subresult {} foreach v [$interp eval [list info vars ${ns}::*]] { if {[array exists $v]} { lappend subresult [list array set [namespace tail $v] [$interp eval [list array get $v]]] } else { lappend subresult [list set [namespace tail $v] [$interp eval [list set $v]]] } } lappend result [list namespace eval $ns [join $subresult {; }]] } return [join $result "; "] }
Zarutian 14. okt 2008: There is one proplem with this. The sub interp knows that it is being serialized.
Lars H: Yes, that's typical of Tcl; information isn't hidden, we just trust our programs to not poke their noses where they aren't supposed to be. I suppose if you really don't trust the interpreter you want to serialise, the you'll just have to interp hide all the sensitive commands and replace them with suitable aliases, like so:
foreach cmd {namespace unset info array set} { interp hide $interp $cmd interp alias $interp $cmd {} $interp invokehidden $cmd }
This way, even if the slave interp has tried to "patch" e.g. unset in an attempt to detect the initial unsettings of errorCode and errorInfo, it will only patch the alias, so serialize still has unhindered access. There are however two holes in these precausions:
The code above also had several quoting errors regarding variable names (assuming that [set $v] and [eval set $v] always did the same thing), but I think I have corrected these.
Related concepts: interp, serializing
AM (15 june 2010) While invoking procedures in another interpreter is easy, exchanging variables between interpreters requires a bit of trickery.