您的位置:首页 > 其它

[转]tcl中varibale变量的跟踪记录

2015-08-29 19:25 225 查看
tcl中进行变量-variable的记录和操作过程记录,使用trace函数可以完成。

参见文章:TCL - info命令和文章

■跟踪变量

TCL提供了trace命令来跟踪一个或多个变量。如果已经建立对一个变量的跟踪,则不论什么时候对该变量进行了读、写、或删除操作,就会激活一个对应的Tcl命令,跟踪可以有很多的用途:
1.监视变量的用法(例如打印每一个读或写的操作)。
2.把变量的变化传递给系统的其他部分(例如一个TK程序中,在一个小图标上始终显示某个变量的当前值)。
3.限制对变量的某些操作(例如对任何试图用非十进制数的参数来改变变量的值的行为产生一个错误。)或重载某些操作(例如每次删除某个变量时,又重新创建它)。
trace命令的语法为:
trace option ?arg arg ...?
其中option有以下几种形式:
trace variable name ops command 这个命令设置对变量name的一个跟踪:每次当对变量name作ops操作时,就会执行command命令。name可以是一个简单变量,也可以是一个数组的元素或者整个数组。
ops可以是以下几种操作的一个或几个的组合:
r 当变量被读时激活command命令。
w 当变量被写时激活command命令。
u 当变量被删除时激活command命令。通过用unset命令可以显式的删除一个变量,一个过程调用结束则会隐式的删除所有局部变量。当删除解释器时也会删除变量,不过这时跟踪已经不起作用了。
当对一个变量的跟踪被触发时,TCL解释器会自动把三个参数添加到命令command的参数列表中。这样command实际上变成了
command name1 name2 op
其中op指明对变量作的什么操作。name1和name2用于指明被操作的变量:
如果变量是一个标量,那么name1给出了变量的名字,而name2是一个空字符串;如果变量是一个数组的一个元素,那么name1给出数组的名字,而name2给出元素的名字;如果变量是整个数组,那么name1给出数组的名字而name2是一个空字符串。为了让你很好的理解上面的叙述,下面举一个例子:
trace variable color w pvar
trace variable a(length) w pvar
proc pvar {name element op} {
if {$element !=""} {
set name ${name}($element)
}
upvar $name x
puts "Variable $name set to $x"
}
上面的例子中,对标量变量color和数组元素a(length)的写操作都会激活跟踪操作pvar。我们看到过程pvar有三个参数,这三个参数TCL解释器会在跟踪操作被触发时自动传递给pvar。比如如果我们对color的值作了改变,那么激活的就是pvar color "" w。我们敲入:
% set color green
Variable color set to green
green
command将在和触发跟踪操作的代码同样的上下文中执行:如果对被跟踪变量的访问是在一个过程中,那么command就可以访问这个过程的局部变量。比如:
proc Hello { } {
set a 2
trace variable b w { puts $a ;list }
set b 3
}
% Hello
2
3
对于被跟踪变量的读写操作,command是在变量被读之后,而返回变量的值之前被执行的。因此,我们可以在command对变量的值进行改变,把新值作为读写的返回值。而且因为在执行command时,跟踪机制会临时失效,所以在command中对变量进行读写不会导致command被递归激活。例如:
% trace variable b r tmp
% proc tmp {var1 var2 var3 } {
upvar $var1 t
incr t 1
}
% set b 2
2
% puts $b
3
% puts $b
4
如果对读写操作的跟踪失败,即command失败,那么被跟踪的读写操作也会失败,并且返回和command同样的失败信息。利用这个机制可以实现只读变量。下面这个例子实现了一个值只能为正整数的变量:
trace variable size w forceInt
proc forceInt {name element op} {
upvar $name x
if ![regexp {^[0-9]*$} $x] {
error "value must b a postive integer"
}
}
如果一个变量有多个跟踪信息,那么各个跟踪被触发的先后原则是:最近添加的跟踪最先被触发,如果有一个跟踪发生错误,后面的跟踪就不会被触发。
trace vdelete name ops command 删除对变量name的ops操作的跟踪。返回值为一个空字符串。
trace vinfo name 这个命令返回对变量的跟踪信息。返回值是一个list,list的每个元素是一个子串,每个子串包括两个元素:跟踪的操作和与操作关联的命令。如果变量name不存在或没有跟踪信息,返回一个空字符串。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: