[英]Manipulate non-global variables from fileevent handler
有沒有一種方法可以從FileEvent處理程序中處理非全局變量? 考慮以下最小服務器:
proc initState {stateName} {
upvar $stateName state
set state(foo) bar
set state(baz) bla
# ...
return
}
proc handleConnection {stateName newsock clientAddress clientPort} {
upvar $stateName state
fconfigure $newsock -blocking 0
fconfigure $newsock -buffering line
fileevent $newsock readable [list handleData $newsock]
return
}
proc handleData {f} {
if {[eof $f]} {
fileevent $f readable {}
close $f
return
}
gets $f line
puts $f ok
# need to modify state here...
return
}
proc runServer {port} {
array set state {}
initState state
socket -server {handleConnection state} $port
vwait forever
}
runServer 1234
是否有可能操縱在runServer
范圍內創建的state
數組,還是使state
成為全局變量的唯一方法?
我對Tcl還是很陌生,如果我使用CI會簡單地將state
指針傳遞到事件處理程序中,但不幸的是Tcl不允許這樣做。 我在這里做任何奇怪的事情,還有更多類似Tcl的方法嗎?
那根本行不通。 問題是Tcl的堆棧幀無法按照您所需的方式持久保存。
解決此問題的標准選項是:
將狀態保存在由“連接令牌”(例如,通道名稱)索引的全局數組中。 請記住,數組是由字符串索引的; 諸如“ sock42,hostname
”之類的復合鍵非常合法。
將狀態保留在以連接令牌命名的命名空間中 。 如果您使用的是Tcl 8.5,則可以使用namespace upvar
命令輕松得多 。
將狀態保存在TclOO 對象中 (需要Tcl 8.6 或 8.5單獨的TclOO軟件包)或使用其他對象系統(例如[incr Tcl],XOTcl;這些可用於許多Tcl版本)。
將狀態保持在協程中 (需要Tcl 8.6)。 這有效地為您提供了一個命名堆棧(並允許您編寫代碼,因此它顯然是“直線”而不是由回調驅動),但是其版本要求非常嚴格 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.