Как получить доступ к списку из proc в глобальном пространстве - PullRequest
1 голос
/ 06 мая 2019

Мне нужно LIST вне процедуры для дальнейшей процессии. Но puts $LIST показывает сообщение об ошибке no such variable.

Я также пробовал upvar 0# LIST LIST вместо global с тем же результатом.

Я подозреваю, что нарушитель спокойствия вызывает proc с "list ..... Если я опускаю" list "при вызове proc, команда global делает то, что должна, но, конечно, код в целом больше не работает должным образом.

proc receiver {chan} {
    global LIST
    set data [gets $chan]
    set LIST [split $data ,]  
}

puts $LIST  

set chan [open com5 r]
fconfigure $chan -mode "9600,n,8,1" -blocking 1 -buffering none -translation binary
fileevent $chan readable [list receiver $chan]

Как я могу получить доступ к LIST в глобальном пространстве за пределами proc?

Ответы [ 3 ]

1 голос
/ 06 мая 2019

Проблема частично в том, что переменная еще не была записана при вызове команды puts, а частично в том, что вы фактически не привыкли работать асинхронно.

Вам нужно подождатькое-что прибыть прежде, чем вы сможете распечатать переменнуюКоманда vwait идеально подходит для этого (поскольку она запускает цикл событий Tcl во время ожидания).Мы можем сказать ему, чтобы он ожидал записи (глобальной) переменной LIST: когда это произойдет, мы можем безопасно прочитать ее.

proc receiver {chan} {
    global LIST
    set data [gets $chan]
    set LIST [split $data ","]  
}

set chan [open com5 r]
fconfigure $chan -mode "9600,n,8,1" -blocking 1 -buffering none -translation binary
fileevent $chan readable [list receiver $chan]

vwait LIST
puts $LIST
0 голосов
/ 06 мая 2019

Это почти нормально, но переменные, поступающие через последовательный порт обновляется каждую секунду

Если это требование, то:

(1) Получить значение, возвращаемое из канала, в процедуре обратного вызова: receiver

(2) Ввести цикл обработки событий только один раз, без привязки к глобальной переменной List и т. П.

proc receiver {chan} {
    set data [gets $chan]
    puts [split $data ","]; # (1) print the return value
}

set chan [open com5 r]
fconfigure $chan -mode "9600,n,8,1" -blocking 1 -buffering none -translation binary
fileevent $chan readable [list receiver $chan]

vwait forever
puts "Quitted from event loop ..."

Это войдет в цикл обработки событий, связанный с неопределенной переменной forever, не установленной в вашем скрипте. Таким образом, он не выйдет, если вы не остановите исполняемый файл (например, tclsh) или если вы не предоставите явное условие завершения, например ::

proc receiver {chan} {
    global counter
    set data [gets $chan]
    puts [split $data ","]; # (1) print the return value
    if {[incr counter] == 5} {
        global forever
        set forever 1; # (2) Exit the event loop, after receiver having been called 5 times
    }
}
0 голосов
/ 06 мая 2019

Я думаю, вы должны объявить LIST глобальным в корневом пространстве имен:

proc receiver {chan} {
    global LIST
    set data [gets $chan]
    set LIST [split $data ,]  
}

global LIST
puts $LIST  

set chan [open com5 r]
fconfigure $chan -mode "9600,n,8,1" -blocking 1 -buffering none -translation binary
fileevent $chan readable [list receiver $chan]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...