2016-06-03 1 views
0

У меня есть файл, хранящий некоторые данные:Использование трассировки для вызова прок, когда значение переменной изменяется TCL

miscellaneous data1 

Файл будет иногда открыт и данные будут изменены.

356 
miscellaneous data2 

данные в файле будут храниться в переменной $ FILEDATA каждые 10 секунд

хранения процедура

данных

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 
} 

Процедура для запуска StoreData каждые 10 секунд

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 отличается от последней итерации сценария, он будет вызывать процедурный ValueChanged? До сих пор я попытался добавить команду трассировки

trace add variable fileData write "valueChanged" 

после вызова

every 10000 {storeData} 

но это просто распечатав сообщение, даже если значение не изменяется.

+0

Всякий раз, когда переменная записывается это будет называться.т. е. всякий раз, когда вы используете команду 'set' для установки значения для отслеживаемой переменной, это будет вызываться. – Dinesh

+0

Я вижу, должен ли я использовать операцию чтения? – James

+0

Нет, все равно это будет напечатано всякий раз, когда он читается. Например, 'puts $ fileData' приведет к тому, что трассировка будет вызвана, так как она включает операцию чтения. Независимо от того, что вас интересует с точки зрения проверки содержимого, это то же самое или другое, вы должны вручную проверить его. Возможно, вам даже не понадобится «trace». – Dinesh

ответ

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

, потому что он будет вызван с тремя аргументами (имя переменной, имя члена, и операции). Даже если вы не используете эти аргументы, вам необходимо убедиться, что процедура может их получить, иначе вызов завершится с ошибкой.

Документация: close, gets, global, info, lappend, open, proc, puts, set, trace, while

1
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 
} 
Смежные вопросы