当变量中的值更改TCL时,使用trace来调用proc

时间:2016-06-03 06:01:43

标签: tcl trace proc

我有一个存储一些数据的文件:

miscellaneous data1

偶尔会打开文件并更改数据。

356
miscellaneous data2

文件中的数据将每隔10秒存储到一个变量$ fileData中

数据存储程序

proc storeData {} {
 global fileData
 if {[info exists fileData]} {
  set fileData ""
 }
 set fp [open file1.txt r]
 while {[gets $fp data] > -1} {
  lappend fileData $data\n
 }
 close $fp
}

每10秒运行一次storeData的过程

proc every {ms body} {
 if 1 $body
 after $ms [list after idle [info level 0]]
}
every 10000 {storeData}

更改fileData中的值时调用的过程

proc valueChanged {} {
 puts "Value in fileData has changed."
}

如何应用trace命令,使得如果fileData中的值与脚本的最后一次迭代不同,它将调用proc valueChanged? 到目前为止,我已经尝试添加跟踪命令

trace add variable fileData write "valueChanged" 

之后

every 10000 {storeData}

但即使值不变,它也只是打印出来的消息。

2 个答案:

答案 0 :(得分:1)

laravelcollective

答案 1 :(得分:1)

部分问题在于,每次调用fileData时,您都会根据文件内容的变化更改变量storeData。更重要的是,您为每次调用多次更改变量:一次重置时,一次为lappend的每一行。修订版storeData,每次调用时更改次数为:

proc storeData {} {
    global fileData
    set temp {}
    set fp [open file1.txt r]
    while {[gets $fp data] > -1} {
        lappend temp $data\n
    }
    set fileData $temp
    close $fp
}

valueChanged命令需要查找实际差异,而不仅仅是接受写入指示更改。另一个全局变量可以包含fileData

的最新已知内容
proc valueChanged args {
    global storedValue fileData
    if {![info exists storedValue]} {
        set storedValue $fileData
    } elseif {$storedValue ne $fileData} {
        puts "Value in fileData has changed."
        set storedValue $fileData
    } else {
        puts "Value in fileData is the same."
    }
}

valueChanged程序需要像这样定义:

proc valueChanged args {
    ...
}

因为它将使用三个参数(变量名,成员名和操作)进行调用。即使您不使用这些参数,您也需要确保程序可以接收它们,否则呼叫将失败。

文档:closegetsglobalinfolappendopenproc,{{3 }},putssettrace