当变量中的值更改TCL时,使用跟踪调用proc

当变量中的值更改TCL时,使用跟踪调用proc,tcl,trace,proc,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] &

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

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命令

trace add variable fileData write "valueChanged" 
打完电话

every 10000 {storeData}

但它只是打印出消息,即使值不变

问题的一部分在于,每次调用
storeData
时,您都会独立于文件内容的更改来更改变量
fileData
。更重要的是,每次调用都要多次更改变量:重置变量时更改一次,对添加到它的
lappend
行更改一次。修订的
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
}
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 {
    ...
}
因为它将用三个参数(变量名、成员名和操作)调用。即使不使用这些参数,也需要确保过程可以接收它们,否则调用将失败


文档:,,,,

问题的一部分在于,每次调用
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 {
    ...
}
因为它将用三个参数(变量名、成员名和操作)调用。即使不使用这些参数,也需要确保过程可以接收它们,否则调用将失败


文档:,,,,

无论何时写入变量,都将调用该变量。i、 e.无论何时使用
set
命令设置跟踪变量的值,都会调用该命令。我明白了,我应该改为使用读取操作吗?不,仍然会在读取时打印该命令。例如,
put$fileData
将触发跟踪,因为它涉及读取操作。无论您对检查内容是否相同感兴趣,都必须手动检查相同的内容。您甚至可能根本不需要
跟踪
。您可以在读取文件内容时立即检查它。无论何时写入变量,都将调用它。i、 e.无论何时使用
set
命令设置跟踪变量的值,都会调用该命令。我明白了,我应该改为使用读取操作吗?不,仍然会在读取时打印该命令。例如,
put$fileData
将触发跟踪,因为它涉及读取操作。无论您对检查内容是否相同感兴趣,都必须手动检查相同的内容。您甚至可能根本不需要
跟踪
。您可以在读取文件内容时立即检查它。