英文:
How do you store the namespace variable and its nested namespace children (its variable, etc) states in a file in TCL?
问题
如何在TCL中将命名空间变量及其嵌套命名空间子项(变量等)的状态保存到文件中?
英文:
How do you save the namespace variable and its nested namespace children (its variable, etc) states in a file in TCL?
答案1
得分: 1
# 将变量内容存储在命名空间树中相当容易,将过程存储在命名空间中也是如此。存储可能存在的其他命令和变量追踪... 要困难得多!此外,这些变量中的值可能会命名临时的事物,比如套接字通道。
# 这里做的是简单的事情,将生成的 Tcl 脚本写入一个打开的通道;写入文件只是对此的一个简单包装。
proc storeNamespace {channel namespaceName} {
# 设置命名空间及其变量
set initBody {}
foreach var [info vars $namespaceName::*] {
# 棘手的一点是,在写入那里的变量之前需要在命名空间中调用 [variable]
append initBody "\n" [list variable [namespace tail $var]]
}
puts $channel [list namespace eval $namespaceName $initBody]
# 现在我们实际上可以将变量的内容写出来
foreach var [info vars $namespaceName::*] {
upvar 1 $var v
# 两种情况,数组和简单变量
if {[array exists v]} {
puts $channel [list array set $var [array get v]]
} else {
puts $channel [list set $var $v]
}
}
# 也保存过程
foreach p [info procs $namespaceName::*] {
# 需要额外的工作来处理带有默认值的参数
set args [lmap a [info args $p] {
if {[info default $p $a def]} {
list $a $def
} else {
list $a
}
}]
# 写入过程定义
puts $channel [list proc $p $args [info body $p]]
}
# 并递归处理子命名空间
foreach ns [namespace children $namespaceName] {
storeNamespace $channel $ns
}
}
# 示例:
storeNamespace stdout ::foo
英文:
Storing the contents of the variables in a tree of namespaces is easy enough, as is storing the procedures in the namespaces. Storing the other commands that might be there and the variable traces... much harder! Plus the values in those variables might name ephemeral things like socket channels.
This does the simple thing, writing a generated Tcl script to an open channel; writing to a file is just a trivial wrapper around this.
proc storeNamespace {channel namespaceName} {
# Set up the namespace and its variables
set initBody {}
foreach var [info vars $namespaceName::*] {
# Tricky point; need to call [variable] in the NS before writing to vars there
append initBody "\n" [list variable [namespace tail $var]]
}
puts $channel [list namespace eval $namespaceName $initBody]
# Now we can actually write the contents of the variables out
foreach var [info vars $namespaceName::*] {
upvar 1 $var v
# Two cases, arrays and simple variables
if {[array exists v]} {
puts $channel [list array set $var [array get v]]
} else {
puts $channel [list set $var $v]
}
}
# Save the procedures too
foreach p [info procs $namespaceName::*] {
# Need to do extra work to handle arguments with defaults
set args [lmap a [info args $p] {
if {[info default $p $a def]} {
list $a $def
} else {
list $a
}
}]
# Write the procedure definition
puts $channel [list proc $p $args [info body $p]]
}
# And recurse for the child namespaces
foreach ns [namespace children $namespaceName] {
storeNamespace $channel $ns
}
}
# Example:
storeNamespace stdout ::foo
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论