如何在全球空间中从proc访问列表

时间:2019-05-06 12:52:33

标签: tcl

我需要proc之外的LIST进行进一步的处理。但是puts $LIST显示错误消息no such variable

我还尝试了upvar 0# LIST LIST而不是global,但结果相同。

我怀疑,麻烦制造者正在使用“列表.....”来调用proc。如果我在调用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]

如何在proc之外的全局空间访问LIST

3 个答案:

答案 0 :(得分:1)

部分原因是调用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

答案 1 :(得分:0)

我认为您必须在根名称空间中将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]

答案 2 :(得分:0)

  

几乎可以,但是通过串行端口传入的变量是   每秒更新

如果这是要求,则:

(1)将通道返回的值打印在回调proc中: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
    }
}