Error processing request
Parameters
CONTENT_LENGTH | 0 |
REQUEST_METHOD | GET |
REQUEST_URI | /revision/recursive+fileevent+accumulator?V=6 |
QUERY_STRING | V=6 |
CONTENT_TYPE | |
DOCUMENT_URI | /revision/recursive+fileevent+accumulator |
DOCUMENT_ROOT | /var/www/nikit/nikit/nginx/../docroot |
SCGI | 1 |
SERVER_PROTOCOL | HTTP/1.1 |
HTTPS | on |
REMOTE_ADDR | 172.70.127.145 |
REMOTE_PORT | 12592 |
SERVER_PORT | 4443 |
SERVER_NAME | wiki.tcl-lang.org |
HTTP_HOST | wiki.tcl-lang.org |
HTTP_CONNECTION | Keep-Alive |
HTTP_ACCEPT_ENCODING | gzip, br |
HTTP_X_FORWARDED_FOR | 18.219.182.76 |
HTTP_CF_RAY | 889908f2db2a29bd-ORD |
HTTP_X_FORWARDED_PROTO | https |
HTTP_CF_VISITOR | {"scheme":"https"} |
HTTP_ACCEPT | */* |
HTTP_USER_AGENT | Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected]) |
HTTP_REFERER | http://wiki.tcl.tk/revision/recursive+fileevent+accumulator?V=6 |
HTTP_CF_CONNECTING_IP | 18.219.182.76 |
HTTP_CDN_LOOP | cloudflare |
HTTP_CF_IPCOUNTRY | US |
Body
Error
Unknow state transition: LINE -> END
-code
1
-level
0
-errorstack
INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {recursive fileevent accumulator} {This technique is from code posted by [DGP] on news:comp.lang.tcl [http://groups-beta.google.com/group/comp.lang.tcl/msg/5dd070690ec8aeb3?hl=en]. The basic idea is to avoid using global variables in a [fileevent] handler by rewriting the handler callback with accumulated state, in a similar way to using an accumulator parameter for recursive calls. Here's a version of the code, which provides a little tclsh-like prompt server:
# Port to accept requests on
set PORT 9000
proc Accept {sock addr port} {
set interp [interp create -safe]
interp alias $interp exit {} close $sock
fileevent $sock readable [list Read $sock $interp {}]
}
proc Prompt {sock interp} {
fileevent $sock writable {}
puts -nonewline $sock {% }
flush $sock
fileevent $sock readable [list Read $sock $interp {}]
}
proc Read {sock interp script} {
fileevent $sock readable {}
if {[catch {gets $sock line} numChars]} {
close $sock
interp delete $interp
return
}
if {$numChars < 0} {
if {[fblocked $sock]} {
fileevent $sock readable [list Read $sock $interp $script]
return
}
if {[eof $sock]} {
close $sock
interp delete $interp
return
}
}
append script $line\n
if {[info complete $script]} {
catch [list $interp eval $script] result
# channel may have closed...
if {[llength [file channels $sock]]} {
fileevent $sock writable [list Write $sock $interp $result]
}
return
}
# **** THIS IS THE MAGIC: *****
# Here we reschedule the fileevent handler in a similar way to
# making a recursive call, with the updated $script argument
# which is used as an accumulator. This relies on the fact that
# scheduling a new fileevent handler overwrites any existing ones.
fileevent $sock readable [list Read $sock $interp $script]
}
proc Write {sock interp result} {
fileevent $sock writable {}
puts $sock $result
fileevent $sock writable [list Prompt $sock $interp]
}
# Start a demo server
socket -server Accept $PORT
vwait forever
[Todd Coram] discusses the same technique and others at [http://www.maplefish.com/todd/tcl_net_idioms.html], in his tips for building high-performance network code in Tcl.
======
<<categories>> Example} regexp2} CALL {my render {recursive fileevent accumulator} {This technique is from code posted by [DGP] on news:comp.lang.tcl [http://groups-beta.google.com/group/comp.lang.tcl/msg/5dd070690ec8aeb3?hl=en]. The basic idea is to avoid using global variables in a [fileevent] handler by rewriting the handler callback with accumulated state, in a similar way to using an accumulator parameter for recursive calls. Here's a version of the code, which provides a little tclsh-like prompt server:
# Port to accept requests on
set PORT 9000
proc Accept {sock addr port} {
set interp [interp create -safe]
interp alias $interp exit {} close $sock
fileevent $sock readable [list Read $sock $interp {}]
}
proc Prompt {sock interp} {
fileevent $sock writable {}
puts -nonewline $sock {% }
flush $sock
fileevent $sock readable [list Read $sock $interp {}]
}
proc Read {sock interp script} {
fileevent $sock readable {}
if {[catch {gets $sock line} numChars]} {
close $sock
interp delete $interp
return
}
if {$numChars < 0} {
if {[fblocked $sock]} {
fileevent $sock readable [list Read $sock $interp $script]
return
}
if {[eof $sock]} {
close $sock
interp delete $interp
return
}
}
append script $line\n
if {[info complete $script]} {
catch [list $interp eval $script] result
# channel may have closed...
if {[llength [file channels $sock]]} {
fileevent $sock writable [list Write $sock $interp $result]
}
return
}
# **** THIS IS THE MAGIC: *****
# Here we reschedule the fileevent handler in a similar way to
# making a recursive call, with the updated $script argument
# which is used as an accumulator. This relies on the fact that
# scheduling a new fileevent handler overwrites any existing ones.
fileevent $sock readable [list Read $sock $interp $script]
}
proc Write {sock interp result} {
fileevent $sock writable {}
puts $sock $result
fileevent $sock writable [list Prompt $sock $interp]
}
# Start a demo server
socket -server Accept $PORT
vwait forever
[Todd Coram] discusses the same technique and others at [http://www.maplefish.com/todd/tcl_net_idioms.html], in his tips for building high-performance network code in Tcl.
======
<<categories>> Example}} CALL {my revision {recursive fileevent accumulator}} CALL {::oo::Obj3224551 process revision/recursive+fileevent+accumulator} CALL {::oo::Obj3224549 process}
-errorcode
NONE
-errorinfo
Unknow state transition: LINE -> END
while executing
"error $msg"
(class "::Wiki" method "render_wikit" line 6)
invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
(class "::Wiki" method "render" line 8)
invoked from within
"my render $name $C"
(class "::Wiki" method "revision" line 31)
invoked from within
"my revision $page"
(class "::Wiki" method "process" line 56)
invoked from within
"$server process [string trim $uri /]"
-errorline
4