Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/recursive+fileevent+accumulator?V=6
QUERY_STRINGV=6
CONTENT_TYPE
DOCUMENT_URI/revision/recursive+fileevent+accumulator
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.127.145
REMOTE_PORT12592
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR18.219.182.76
HTTP_CF_RAY889908f2db2a29bd-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_REFERERhttp://wiki.tcl.tk/revision/recursive+fileevent+accumulator?V=6
HTTP_CF_CONNECTING_IP18.219.182.76
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

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