当变量中的值发生变化时使用 trace 调用 proc TCL

Using trace to call proc when value in variable changes TCL

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

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."
}

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

trace add variable fileData write "valueChanged" 

调用后

every 10000 {storeData}

但即使值未更改,它也只是打印出消息。

set fileData {}
proc storeData {} {
    global fileData
    set fp [open file1.txt r]
    set localData {}
    while {[gets $fp data] > -1} {
        lappend localData $data\n
    }
    if {$localData ne $fileData} {
        # Resetting the global 'fileData' content
        set fileData $localData
        puts "content changed"
    }
    close $fp
}

部分问题是您在每次调用 storeData 时独立于文件内容的变化而更改变量 fileData。更重要的是,每次调用都会多次更改变量:重置变量时一次,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 {
    ...
}

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

文档:close, gets, global, info, lappend, open, proc, puts, set, trace, while