与过程相关的小查询范围
proc lappend {args} {
set a $args
lappend a testing ;# want to call the inbuilt tcl lappend command
puts "$a"
}
set list {new to tcl}
lappend $list
与过程相关的小查询范围
proc lappend {args} {
set a $args
lappend a testing ;# want to call the inbuilt tcl lappend command
puts "$a"
}
set list {new to tcl}
lappend $list
如果你只是这样做,它不会起作用。它会替换标准的 lappend
并导致无限递归(或者触发堆栈深度检查)。有几种方法可以解决这个问题。
如果你的代码在一个命名空间中,它会优先解析该命名空间内的 lappend
,只有当本地搜索失败时才会使用全局命名空间。你可以像这样使用它:
namespace eval myNS {
proc lappend {args} {
set a $args
::lappend a testing ;# Force the use of the global lappend command
puts "$a"
}
set list {new to tcl}
lappend $list
}
这有几种可能的变化方式,namespace eval myNS {source example.tcl}
是其中一种比较有趣的方式,因为它使得代码在很大程度上独立于命名空间(译者注:即可以不考虑命名空间)。
lappend
命令你也可以像这样移动标准命令:
rename lappend lappend_original
proc lappend {args} {
set a $args
lappend_original a testing
puts "$a"
}
set list {new to tcl}
lappend $list
只要没有太多代码争夺实际的原始命令,这种技术就可以正常工作。多年来,许多Tcl脚本都在使用它。
当然,lappend
命令并不是一个你真正想要替换的命令,因为它在很多Tcl库代码中都得到广泛使用。对于确定一个代码片段实际调用了lappend
及其传递的参数是什么的问题,更好的方法是使用执行跟踪。(链接指向的是Tcl 8.6文档,但这个API自Tcl 8.4以来就存在,因此应该可以使用。)
proc runningLappend {cmdAndArgs operation} {
puts [lrange $cmdAndArgs 1 end]
}
trace add execution lappend enter runningLappend