【问题标题】:Using trace to call proc when value in variable changes TCL当变量中的值更改时使用跟踪调用 proc TCL
【发布时间】:2016-06-03 06:01:43
【问题描述】:

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

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 命令为跟踪变量设置值时,都会调用它。
  • 我明白了,我应该改用读取操作吗?
  • 不,仍然会在阅读时打印。例如,puts $fileData 将导致跟踪触发,因为它涉及读取操作。无论您对检查内容是否相同感兴趣,都必须手动检查。你甚至可能根本不需要trace
  • 在阅读文件内容的同时可以直接查看。

标签: tcl trace proc


【解决方案1】:

部分问题在于,每次调用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, trace, p>

【讨论】:

    【解决方案2】:
    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 2018-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多