如果变量只是不确定的,最简单的方法是用一个定义来修补程序:
proc foo [info args foo] "set bar \"hello, world\" ; [info body foo]"
您也可以使用读取跟踪和助手命令做到这一点。这消除了我上面提到的问题,其中本地任务会破坏您想要注入的值。
原始程序,带有一个将局部变量设置为稍后打印的值的附加命令。
proc foo args {
set bar foobar
puts "$bar"
}
% foo
foobar
创建一个全局变量(名称是否相同并不重要)。
set bar "hello, world"
创建一个帮助命令获取本地变量的名称,链接到它,并赋予全局变量到它的价值。既然我们已经知道了名字,我们可以在程序中对它进行硬编码,但这更灵活。
proc readbar {name args} {
upvar 1 $name var
global bar
set var $bar
}
将跟踪添加到foo
过程的主体。只要读取本地变量bar
,即会尝试检索其值,就会触发跟踪。跟踪触发时,将调用命令readbar
:它将用全局设置值覆盖变量的当前值。
proc foo [info args foo] "trace add variable bar read readbar; [info body foo]"
% foo
hello, world
如果不希望污染与助手命令的命名空间,可以使用,而不是一个匿名函数:
proc foo [info args foo] [format {trace add variable bar read {apply {{name args} {
upvar 1 $name var
global bar
set var $bar
}}} ; %s} [info body foo]]
文档: apply, format, global, info , proc, puts, set, trace, upvar, Syntax of Tcl regular expressions
可以设置具有相同名称的全局变量并链接到它,例如通过在程序主体的开头添加一个'global'调用,就像Glenn所建议的那样。但它不会起作用。在程序代码中的某处,在打印“bar”的值之前,该值将被设置为现在使用的值。链接到全局变量不能防止发生这种变化。 –
如果我看到这个问题,我可能会说同样的事情,但功能实际上已经坏了,我不能修复它。很显然,代码已经从其他地方复制过来,但是这个变量肯定是未定义的。 (或者我误解了你的意思?) – user234461
不,误解是我的。我只是假设没有人会用一个有未定义变量的程序。 –