Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/vwait?V=43
QUERY_STRINGV=43
CONTENT_TYPE
DOCUMENT_URI/revision/vwait
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
REMOTE_ADDR172.70.127.114
REMOTE_PORT24410
SERVER_PORT8888
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip
HTTP_X_FORWARDED_FOR18.188.152.157
HTTP_CF_RAY886630498cc013fe-ORD
HTTP_X_FORWARDED_PROTOhttp
HTTP_CF_VISITOR{"scheme":"http"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP18.188.152.157
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 vwait vwait\ -\ Process\ events\ until\ a\ variable\ is\ written\n<<br>>\nhttp://www.purl.org/tcl/home/man/tcl/TclCmd/vwait.htm\n\n\n\nThis\ command\ enters\ the\ Tcl\ \[event\ loop\]\ to\ process\ events,\ blocking\ the\ application\ if\ no\ events\ are\ ready.\ \ It\ continues\ processing\ events\ until\ some\ event\ handler\ sets\ the\ value\ of\ variable\ ''varName''.\ \ Once\ ''varName''\ has\ been\ set,\ the\ '''vwait'''\ command\ will\ return\ as\ soon\ as\ the\ event\ handler\ that\ modified\ ''varName''\ completes.\ ''VarName''\ must\ globally\ scoped\ (either\ with\ a\ call\ to\ '''\[global\]'''\ for\ the\ ''varName'',\ or\ with\ the\ full\ namespace\ path\ specification).\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/vwait.htm%|%official\ man\ page\]:\ \ \ \nIn\ some\ cases\ the\ '''vwait'''\ command\ may\ not\ return\ immediately\ after\ ''varName''\ is\ set.\ This\ can\ happen\ if\ the\ event\ handler\ that\ sets\ ''varName''\ does\ not\ complete\ immediately.\ For\ example,\ if\ an\ event\ handler\ sets\ ''varName''\ and\ then\ itself\ calls\ '''vwait'''\ to\ wait\ for\ a\ different\ variable,\ then\ it\ may\ not\ return\ for\ a\ long\ time.\ During\ this\ time\ the\ top-level\ '''vwait'''\ is\ blocked\ waiting\ for\ the\ event\ handler\ to\ complete,\ so\ it\ cannot\ return\ either.\n\n<<discussion>>\n\ \ \ \[event-oriented\ programming\]:\ \ \ \n'''Do\ not\ use\ vwait\ without\ checking\ for\ tk\ or\ tclsvc!'''\n\n''\[Jeff\ Hobbs\]\ spoke\ in\ the\ \[Tcl\ chatroom\]:''\ vwait\ should\ always\ be\ protected\ by\nvwait\ forever\n\ \ if\ \{!\[info\ exists\ tk_version\]\ &&\ !\[info\ exists\ tcl_service\]\}\ \{\ ...\n======\nWhy?\ \ \[CL\]\ says\ it's\ to\ avoid\ the\ lockup\ of\ duelling\ vwaits--'cause\ \[Tk\]\ and\ \[tclsvc\]\ launch\ their\ own.\n\n\[PS\]\ 9Mar04\ For\ example:\ this\ script,\ which\ implements\ a\ TCP\ server\ in\ tclsh\ and\ wish,\ will\ not\ exit\ properly\ when\ you\ close\ its\ main\ window.\n======\n\ proc\ accept\ \{\ channel\ peer\ port\ \}\ \{\n\ \ \ \ close\ \$channel\n\ \}\n\ socket\ -server\ accept\ 5000\n\ vwait\ forever\n\nAfter\ you\ close\ the\ window,\ the\ wish\ app\ does\ not\ exit,\ but\ remains\ fully\ active\ in\ memory.\n\n'''\[DGP\]'''\ Note\ that\ this\ discussion\ is\ essentially\ another\nvote\ in\ favor\ of\ Tk\ Feature\ Request\ 456548\n\[http://sf.net/tracker/?func=detail&aid=456548&group_id=12997&atid=362997\].\n\nThe\ flaw\ here\ is\ in\ Tk's\ continued\ assumptions\ about\ being\ in\ wish,\nrather\ than\ being\ an\ independent\ package\ that\ might\ be\ loaded\ into\ any\ Tcl\ interp.\ \ There's\ nothing\ wrong\ with\ \[\[vwait\]\]\ (at\ least\nnothing\ revealed\ in\ this\ discussion.\ :)\ ).\n----\n\n\[Chris\ Nelson\]\ said\ \[http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/3ebbe18159a8efac?tvc=2&q=multiple+vwaits%|%these\ golden\ words%|%\]\ on\ \[the\ comp.lang.tcl\ newsgroup\]:\n\n''Multiple\ vwaits\ nest,\ they\ do\ not\ happen\ in\ parallel.\ \ The\ outermost\ vwait\ cannot\ complete\ until\ all\ others\ return.''\n\n----\n\n'''vwait\ forever''':\ ''Wish''\ has\ a\ built-in\ event\ loop.\ Tclsh\ has\ one\ too\ but\ enters\ that\ only\ on\ demand,\ for\ which\ the\ \[idiom\]\ is\ to\ write\ at\ the\ end\ of\ code\n======\n\ vwait\ forever\n======\n(''forever''\ being\ the\ name\ of\ a\ variable\ that\ is\ presumably\ never\ used,\ but\ you\ can\ set\ ''forever''\ to\ any\ value\ to\ terminate\ such\ a\ Tcl\ script).\ ''RS''\nSee\ the\ note\ below\ about\ namespaces\ -\ missing\ this\ note\ results\ in\ problems\ that\ occur\ quite\ commonly!\n(See\ the\ note\ below\ about\ namespaces\ -\ missing\ this\ note\ results\ in\ problems\ that\ occur\ quite\ commonly!)\n\n----\n\n'''Timeout\ for\ vwait''':\ Wai\ Shun\ Au\ wrote\ in\ \[the\ comp.lang.tcl\ newsgroup\]:\nafter\ 30000\ \{set\ a\ \$a\}\n\ after\ 30000\ \{set\ a\ \$a\}\n\ vwait\ a\n\n\n\[Jeffrey\ Hobbs\]\ commented:\ \ You\ found\ the\ standard\ way,\ but\ you\ have\ to\ go\ a\n\[Jeffrey\ Hobbs\]\ commented:\nYou\ found\ the\ standard\ way,\ but\ you\ have\ to\ go\ a\ bit\ further\ to\ avoid\ weird\ bugs.\ \ Cache\ the\ \[after\]\ id\ and\ make\ sure\ to\ cancel\ it\ following\ the\ ''vwait''\ (no\ \[catch\]\ needed\ -\ if\ the\ after\ id\ no\ longer\ exists,\ because\ it\ was\ triggered,\ ''after\ cancel''\ doesn't\ care).\ \ That\ way\ you\ won't\ get\ ''a''\ being\ reset\ no\ matter\ what\ in\ 30\ secs.\n----\n\n\[DKF\]:\ \ You\ can\ '''`vwait`\ on\ several\ variables\ simultaneously'''\ as\ long\ as\nYou\ can\ '''\[\[vwait\]\]\ on\ several\ variables\ simultaneously'''\ as\ long\ as\ all\ those\ variables\ are\ in\ the\ same\ array,\ and\ you\ are\ happy\ for\ any\ set\ of\ the\ array\ to\ cause\ the\ \[\[vwait\]\]\ to\ terminate.\ \ Do\ this\ by\ making\ the\ \[\[vwait\]\]\ be\ on\ the\ overall\ array,\ and\ not\ any\ element\ of\ it.\ \ ''\[DKF\]''\n----\n\n\[BBH\]:\ \ Actually,\ you\ can\ combine\ the\ multiple\ variable\ &\ timeout\ nicely\nActually,\ you\ can\ combine\ the\ multiple\ variable\ &\ timeout\ nicely\ without\ the\ variables\ having\ to\ be\ related,\ and\ the\ timer\ won't\ affect\ the\ actual\ variables,\ Demonstrated\ by\ this\ code\ taken\ from\ dissussion\ on\ \[the\ comp.lang.tcl\ newsgroup\]\ (most\ of\ the\ original\ work\ by\ \[Donald\ Porter\],\ that\ I\ tweaked\ a\ little\ to\ add\ timeout\ option).\ ''\[BBH\]''\nkenstir:\ \ I\ have\ further\ tweaked\ this\ version\ of\ waitForAny\ that\ returns\ the\nI\ have\ further\ tweaked\ this\ version\ of\ waitForAny\ that\ returns\ the\ var\ (or\ vars)\ that\ got\ set\ during\ the\ vwait.\ \ This\ allows\ you\ to\ build\ a\ robust\ asynchronous\ queue.\ \ I'm\ submitting\ it\ as\ a\ patch\ to\ tcllib.sourceforge.net\ along\ with\ tests.\ \ ''kenstir''\nnamespace\ eval\ control\ \{\n\ namespace\ eval\ control\ \{\n\ \ \ \ variable\ waitForAnyKey\ 0\n\n\ \ \ \ #\ new\ \"vwait\"\ that\ takes\ multiple\ variables\ and/or\ optional\ timeout\n\ \ \ \ #\ usage:\ \ waitForAny\ ?timeout?\ variable\ ?variable\ ...?\n\ \ \ \ proc\ waitForAny\ \{args\}\ \{\n\ \ \ \ \ \ \ \ variable\ waitForAnyArray\n\ \ \ \ \ \ \ variable\ waitForAnyArray\n\ \ \ \ \ \ \ variable\ waitForAnyKey\n\ \ \ \ \ \ \ \ #\ if\ first\ arg\ is\ a\ number,\ then\ that\ is\ max\ wait\ time\n\ \ \ \ \ \ \ #\ if\ first\ arg\ is\ a\ number,\ then\ that\ is\ max\ wait\ time\n\ \ \ \ \ \ \ if\ \{\[string\ is\ int\ \[lindex\ \$args\ 0\]\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ set\ timeout\ \[lindex\ \$args\ 0\]\n\ \ \ \ \ \ \ \ \ \ set\ args\ \[lrange\ \$args\ 1\ end\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ #\ create\ trigger\ script\ that\ will\ cause\ vwait\ to\ fall\ thru\n\ \ \ \ \ \ \ #\ create\ trigger\ script\ that\ will\ cause\ vwait\ to\ fall\ thru\n\ \ \ \ \ \ \ #\ (trailing\ comment\ is\ to\ eat\ appended\ args\ in\ trace\ command)\n\ \ \ \ \ \ \ set\ index\ \"Key\[incr\ waitForAnyKey\]\"\n\ \ \ \ \ \ \ set\ trigger\ \"\[namespace\ code\ \[list\ set\ waitForAnyArray(\$index)\ 1\]\]\ \;#\"\n\ \ \ \ \ \ \ \ #\ create\ trace\ to\ trip\ trigger\n\ \ \ \ \ \ \ #\ create\ trace\ to\ trip\ trigger\n\ \ \ \ \ \ \ foreach\ var\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ uplevel\ \\#0\ \[list\ trace\ variable\ \$var\ w\ \$trigger\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ #\ set\ timer\ is\ user\ requested\ one\n\ \ \ \ \ \ \ #\ set\ timer\ is\ user\ requested\ one\n\ \ \ \ \ \ \ if\ \{\[info\ exists\ timeout\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ set\ timerId\ \[after\ \$timeout\ \$trigger\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ vwait\ \[namespace\ which\ -variable\ waitForAnyArray\](\$index)\n\ \ \ \ \ \ \ \ #\ remove\ all\ traces\n\ \ \ \ \ \ \ #\ remove\ all\ traces\n\ \ \ \ \ \ \ foreach\ var\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ uplevel\ \\#0\ \[list\ trace\ vdelete\ \$var\ w\ \$trigger\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ #\ cancel\ timer\n\ \ \ \ \ \ \ #\ cancel\ timer\n\ \ \ \ \ \ \ if\ \[info\ exists\ timerId\]\ \{\n\ \ \ \ \ \ \ \ \ \ after\ cancel\ \$timerId\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ #\ cleanup\n\ \ \ \ \ \ \ unset\ waitForAnyArray(\$index)\n\}\n\ \}\n\n----\n\n'''vwait\ in\ namespaces:'''\ The\ varName\ must\ be\ globally\ qualified\ as\ if\ in\ a\ binding,\ even\ if\ the\ vwait\ is\ inside\ a\ ''namespace\ eval'':\nnamespace\ eval\ foo\ \{\n\ namespace\ eval\ foo\ \{\n\ \ \ \ \ \ \ vwait\ bar\ \ \ \ \ \ \ \ \;#\ will\ never\ fire\n\ \ \ \ \ \ \ vwait\ ::foo::bar\ \;#\ does\ the\ job\n\ \ \ \ variable\ bar\ \ \ \ \ \;#\ These\ two\ lines\ also\ do\ the\ job\n\ \ \ \ \ \ \ variable\ bar\ \ \ \ \ \;#\ These\ two\ lines\ also\ do\ the\ job\n\ \ \ \ \ \ \ vwait\ \[namespace\ which\ -variable\ bar\]\ \ \ \ \;#\ DGP\n\ \}\ \;#\ RS\n\n----\nA\ majority\ of\ the\ coding\ questions\ received\ in\ \[comp.lang.tcl\]\nA\ majority\ of\ the\ coding\ questions\ received\ in\ \[the\ comp.lang.tcl\ newsgroup\]\ about\ vwait\ appear\ to\ result\ from\ deep\ misunderstandings\ of\ the\ command\ (as\ opposed\ to\ mere\ syntactic\ confusion,\ for\ example).\ \[Bruce\ Hartweg\]\ has\ rightly\ advised\ that\ its\ proper\ use\ is\ restricted:\ \ \"IMHO\ vwaits\ shouldn't\ be\ used\ too\ much\ (the\ nesting\ issue\ creates\ unexpected\ results)\ because\ you\ are\ trying\ to\ force\ a\ synchronous\ approach\nin\ an\ event\ world\ -\ It\ is\ much\ better\ to\ keep\ everything\ event\ driven.\ Occasionally\ for\ simple\ things\ (like\ dialogs)\ to\ use\ a\ vwait\ to\ avoid\ having\ to\ break\ something\ the\ has\ a\ couple\ of\ file\ picks\ and/or\ confirmations\ into\ umpteen\ parts\ has\ its\ place.\"\ \ \[KBK\]\ agrees\ that\ the\ \[Tcl\ event\ loop\]\ is\ widely\ misunderstood\ and\ discusses\ related\ issues\ in\ \[Update\ considered\ harmful\]\ and\ the\ pages\ to\ which\ it\ links.\nin\ an\ event\ world,\ it\ is\ much\ better\ to\ keep\ everything\ event\ driven.\n\nPackages\ such\ as\ \[Tk\]\ and\ \[tclsvc\]\ themselves\ call\ `vwait`.\ \ To\ avoid\ nested\ `vwait`\ calls:\nThis\ little\ program\ demonstrates\ what\ \[Chris\ Nelson\]\ stated\ above\ (vwaits\ nest):\nset\ ::time\ 0\n\ set\ ::time\ 0\n\ set\ ::a\ 0\n\ set\ ::b\ 0\nproc\ a_vwait\ \{\}\ \{\n\ proc\ a_vwait\ \{\ \}\ \{\n\ \ \ \ \ puts\ \"Waiting\ 15\ sec\ for\ ::a\"\n\ \ \ \ \ vwait\ ::a\n\ \ \ \ \ puts\ \"::a\ set\"\n\ \}\nproc\ b_vwait\ \{\}\ \{\n\ proc\ b_vwait\ \{\ \}\ \{\n\ \ \ \ \ puts\ \"Waiting\ 30\ sec\ for\ ::b\"\n\ \ \ \ \ vwait\ ::b\n\ \ \ \ \ puts\ \"::b\ set\"\n\ \}\n\nproc\ timer\ \{\}\ \{\n\ proc\ timer\ \{\ \}\ \{\n\ \ \ \ \ incr\ ::time\ 1\n\ \ \ \ \ puts\ \"\$::time\ sec\"\n\ \ \ \ \ if\ \{\$::time\ ==\ 35\}\ \{\n\ \ \ \ \ \ \ \ \ exit\n\ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ after\ 1000\ timer\n\ \ \ \ \ \}\n\ \}\nafter\ 1\ a_vwait\n\n\ after\ 1\ a_vwait\n\ after\ 5\ b_vwait\n\ after\ 10\ timer\nafter\ 15000\ \{set\ ::a\ 0\}\n\n\ after\ 15000\ \{set\ ::a\ 0\}\n\ after\ 30000\ \{set\ ::b\ 0\}\nvwait\ forever\n\ vwait\ forever\n\n\nWhen\ you\ understand\ this\ code\ snippit,\ you'll\ be\ free\ from\ the\ dangers\ of\ haphazardly\ using\ vwait.\n\n----\n\[Marty\ Backe\]\n15\ August\ 2002\n\n\nChristian\ Klugesherz\ 04\ December\ 2009:\ To\ understand\ what\ really\ happens,\ just\ replace\ the\ above\ timer\ proc,\ by\ adding\ \[after\ info\]\ which\ shows\ the\ existing\ event\ handler\ queue\ \nproc\ timer\ \{\}\ \{\n\ proc\ timer\ \{\ \}\ \{\n\ \ \ \ \ incr\ ::time\ 1\n\ \ \ \ \ puts\ \"\$::time\ sec\"\n\ \ \ \ \ puts\ \[after\ info\]\n\ \ \ \ \ if\ \{\$::time\ ==\ 35\}\ \{\n\ \ \ \ \ \ \ \ \ exit\n\ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ after\ 1000\ timer\n\ \ \ \ \ \ \ \ \ #puts\ \[after\ info\]\n\ \ \ \ \ \}\n\ \}\n\n----\n\nPeter\ Newman\ 9\ March\ 2004:\ '''Wish\ Is\ Buggy!'''\ It\ seems\ to\ me\ that\ all\ these\ problems\ with\ \[vwait\],\ \[tkwait\],\ \[update\]\ and\ ''people\ not\ understanding\ the\ event\ loop'',\ etc\ -\ are\ due\ to\ the\ inherently\ defective\ (in\ my\ opinion\ buggy)\ design\ of\ wish\ -\ in\ that\ it\ automatically\ appends\ the\ event\ loop\ onto\ the\ scripts\ it\ runs.\nPeter\ Newman\ 2004-03-09:\ '''Wish\ Is\ Buggy!'''\ It\ seems\ to\ me\ that\ all\ these\n\n\ pack\ \[button\ .mybutton\ -text\ \"Hello\ World!\"\ -command\ exit\]\ \;\n======\nIt's\ buggy!\ I\ forget\ to\ call\ the\ event\ loop.\ So\ it\ does\ nothing.\ But\ wish\ will\ run\ it\ Ok.\ So\ wish's\ bug\ cancels\ out\ my\ bug\ -\ and\ the\ bug\ in\ my\ program\ gets\ overlooked.\ Almost\ all\ programs\ on\ this\ Wiki\ are\ like\ that.\ As\ written\ by\ the\ programmer,\ there's\ no\ call\ to\ the\ event\ loop.\nNow\ with\ \"Hello\ World\"\ programs\ it\ probably\ doesn't\ matter.\ But\ with\nNow\ with\ \"Hello\ World\"\ programs\ it\ probably\ doesn't\ matter.\ But\ with\ complicated\ real\ world\ programs\ the\ event\ loop\ matters\ a\ lot.\ But\ wish\ permits\ and\ encourages\ Tcl\ programmers\ to\ ignore\ the\ event\ loop.\ We\ only\ worry\ about\ it\ when\ the\ roof\ caves\ in!\ Then\ we\ find\ out\ we\ haven't\ got\ a\ clue\ how\ it\ works.\ Or\ how\ to\ write\ code\ that\ handles\ the\ event\ loop\ properly.\ (Then\ it's\ thank\ God\ for\ pages\ like\ this\ on\ the\ Wiki,\ as\ you\ try\ and\ figure\ it\ out.)\nThe\ solution\ is\ to\ get\ rid\ of\ the\ auto-appending\ the\ event\ loop\ from\ wish.\ And\nThe\ solution\ is\ to\ get\ rid\ of\ the\ auto-appending\ the\ event\ loop\ from\ wish.\ And\ force\ Tcl\ programmers\ to\ learn\ and\ think\ about\ the\ event\ loop\ from\ the\ first,\ and\ with\ every\ subsequent,\ script\ they\ write.\n----\n\n\[schlenk\]\ Not\ really,\ wish\ is\ ok,\ but\ there\ are\ tendencies\ to\ get\ rid\ of\ it\ in\ favor\ of\ tclsh\ and\ package\ require\ Tk.\ Tk\ starts\ the\ event\ loop\ by\ default,\ so\ there\ isn't\ any\ bug.\ If\ you\ use\ Tk,\ you\ have\ a\ running\ event\ loop.\ Why\ make\ things\ more\ complex\ by\ forcing\ people\ to\ require\ the\ event\ loop\ explicitly\ if\ it\ is\ clear\ they\ need\ it?\n\[schlenk\]:\ \ Not\ really,\ wish\ is\ ok,\ but\ there\ are\ tendencies\ to\ get\ rid\ of\ it\n\n\[PS\]\ 9mar04:\ I'd\ have\ to\ agree\ with\ schlenk\ that\ the\ current\ wish\ behaviour\ is\ the\ right\ thing,\ but\ the\ whole\ reason\ I\ moved\ the\ 'check\ for\ tk'\ remark\ to\ the\ top\ of\ the\ page\ is\ that\ I\ was\ bitten\ by\ it\ *again*.\ Currently,\ if\ you\ want\ the\ 'default'\ Tcl\ event\ loop,\ the\ recommended/standard\ way\ seems\ to\ be\ to\ call\ \[\[vwait\ forever\]\].\ But\ there\ are\ more\ and\ more\ script\ out\ there\ that\ run\ in\ multiple\ environments,\ with\ different\ capabilities,\ and\ more\ will\ emerge.\ Is\ checking\ for\ tk\ and\ tclsvr\ enough\ right\ now?\ Probably.\ Will\ it\ be\ in\ the\ future?\ Probably\ not.\ What\ we\ really\ need\ is\ a\ function\ that\ I\ can\ call\ to\ start\ the\ event\ loop,\ which\ -by\ default-\ will\ never\ return.\ Something\ like:\ninterp\ eventloop\n\ interp\ eventloop\n#\ or\ just\n\ #\ or\ just\n\ eventloop\n#\ and\ for\ the\ special\ case\ which\ needs\ it:\n\ #\ and\ for\ the\ special\ case\ which\ needs\ it:\n\{\ ...\ appInitCode\ \}\n\ \{\ ...\ appInitCode\ \}\n\ eventloop\ -pleaseReturnIfPossible\n\ \{\ ...\ appCleanupCode\ \}\n\nOr\ bastardise\ vwait\ to\ do\ the\ same,\ when\ called\ with\ forever\ as\ its\ first\ argument\ (which\ would\ probably\ break\ things).\ And\ maybe\ \[\[interp\ eventloop\ \{script\}\]\]\ to\ provide\ the\ appropriate\ eventloop\ handler\ code.\n\n\[NEM\]\ It\ is\ worth\ pointing\ out\ here\ that\ \[tk_messageBox\]\ calls\ vwait\ internally\ (at\ least\ on\ UNIX).\ This\ has\ been\ a\ cause\ of\ several\ bugs\ in\ event\ driven\ code\ I\ have\ written.\ All\ the\ advice\ given\ on\ this\ page\ about\ not\ calling\ vwait\ should\ also\ apply\ to\ tk_messageBox.\ In\ particular,\ don't\ do\ something\ like\ the\ following:\nfileevent\ \$fd\ readable\ \[list\ readdata\ \$fd\]\n\ fileevent\ \$fd\ readable\ \[list\ readdata\ \$fd\]\n\ proc\ readdata\ \{fd\}\ \{\n\ \ \ \ set\ line\ \[gets\ \$fd\]\n\ \ \ \ #\ Some\ other\ stuff...\n\ \ \ \ tk_messageBox\ ...\n\ \ \ \ #\ Some\ more\ stuff...\n\}\n\ \}\n\nThe\ problem\ is\ that\ the\ internal\ vwait\ means\ that\ your\ readdata\ proc\ will\ likely\ be\ re-entered,\ causing\ all\ kinds\ of\ mayhem\ to\ ensue.\ The\ way\ I\ coded\ around\ this\ was\ to\ implement\ my\ own\ dialog\ box\ code,\ which\ took\ a\ callback:\n======\n\ messagebox\ ...\ -command\ \[list\ dosomething\ ...\]\nBut\ then,\ you\ still\ have\ to\ deal\ with\ what\ to\ do\ with\ events\ that\ come\ in\ while\nBut\ then,\ you\ still\ have\ to\ deal\ with\ what\ to\ do\ with\ events\ that\ come\ in\ while\ the\ dialog\ is\ still\ raised.\ (Do\ you\ process\ them,\ or\ should\ you\ wait\ until\ the\ dialog\ box\ is\ dismissed?)\ I\ never\ really\ decided\ what\ the\ ''correct''\ behaviour\ in\ this\ situation\ would\ be.\n\nIn\ case\ it\ matters\ to\ you,\ this\ quickie\ will\ prevent\ recursive\ \[\[vwait\]\]\ while\ permitting\ iterative\ \[\[vwait\]\]\ -\ \[\[\[CMcC\]\]\]\n======\nrename\ ::vwait\ ::vwait_org\n\ \ \ rename\ ::vwait\ ::vwait_org\n\ \ \ proc\ ::vwait\ \{var\}\ \{\n\ \ \ \ \ \ \ rename\ ::vwait\ ::no_vwait\n\ \ \ \ \ \ \ set\ result\ \[uplevel\ 1\ vwait_org\ \$var\]\n\ \ \ \ \ \ \ rename\ ::no_vwait\ ::vwait\n\ \ \ \ \ \ \ return\ \$result\n\ \ \ \}\n\n\nKen:\ I\ have\ one\ a\ problem\ with\ the\ follow\ code,\ i\ intended\ to\ transfer\ control\ to\ other\ parts\ of\ my\ program\ so\ i\ intend\ embed\ to\ use\ this\ code\ into\ my\ program\ to\ halt\ the\ procession\ of\ one\ function\ and\ go\ to\ other\ function\ which\ would\ call\ it\ again?\ Below\ is\ the\ code\nset\ Flag\ 0\n\ \ \ \ \ \ \ \ \ set\ Flag\ 0\n\ \ \ \ \ \ \ \ \ if\ \{\$Flag\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ continue\n\ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ vwait\ Flag\ \}\n\nbut\ for\ this\ code\ it\ seems\ that\ it\ would\ prompt\ an\ error\ code\ which\ is\ \"can't\n\nbut\ for\ this\ code\ it\ seems\ that\ it\ would\ prompt\ an\ error\ code\ which\ is\ \"can't\ wait\ for\ variable\ Flag\"\ if\ flag\ stays\ at\ 0.\ So\ how\ should\ i\ proceed\ so\ that\ it\ would\ not\ prompt\ this\ error\ code.\n\n<<discussion>>\n\n<<categories>>\ Tcl\ syntax\ help\ |\ Arts\ and\ Crafts\ of\ Tcl-Tk\ Programming\ |\ Command regexp2} CALL {my render vwait vwait\ -\ Process\ events\ until\ a\ variable\ is\ written\n<<br>>\nhttp://www.purl.org/tcl/home/man/tcl/TclCmd/vwait.htm\n\n\n\nThis\ command\ enters\ the\ Tcl\ \[event\ loop\]\ to\ process\ events,\ blocking\ the\ application\ if\ no\ events\ are\ ready.\ \ It\ continues\ processing\ events\ until\ some\ event\ handler\ sets\ the\ value\ of\ variable\ ''varName''.\ \ Once\ ''varName''\ has\ been\ set,\ the\ '''vwait'''\ command\ will\ return\ as\ soon\ as\ the\ event\ handler\ that\ modified\ ''varName''\ completes.\ ''VarName''\ must\ globally\ scoped\ (either\ with\ a\ call\ to\ '''\[global\]'''\ for\ the\ ''varName'',\ or\ with\ the\ full\ namespace\ path\ specification).\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/vwait.htm%|%official\ man\ page\]:\ \ \ \nIn\ some\ cases\ the\ '''vwait'''\ command\ may\ not\ return\ immediately\ after\ ''varName''\ is\ set.\ This\ can\ happen\ if\ the\ event\ handler\ that\ sets\ ''varName''\ does\ not\ complete\ immediately.\ For\ example,\ if\ an\ event\ handler\ sets\ ''varName''\ and\ then\ itself\ calls\ '''vwait'''\ to\ wait\ for\ a\ different\ variable,\ then\ it\ may\ not\ return\ for\ a\ long\ time.\ During\ this\ time\ the\ top-level\ '''vwait'''\ is\ blocked\ waiting\ for\ the\ event\ handler\ to\ complete,\ so\ it\ cannot\ return\ either.\n\n<<discussion>>\n\ \ \ \[event-oriented\ programming\]:\ \ \ \n'''Do\ not\ use\ vwait\ without\ checking\ for\ tk\ or\ tclsvc!'''\n\n''\[Jeff\ Hobbs\]\ spoke\ in\ the\ \[Tcl\ chatroom\]:''\ vwait\ should\ always\ be\ protected\ by\nvwait\ forever\n\ \ if\ \{!\[info\ exists\ tk_version\]\ &&\ !\[info\ exists\ tcl_service\]\}\ \{\ ...\n======\nWhy?\ \ \[CL\]\ says\ it's\ to\ avoid\ the\ lockup\ of\ duelling\ vwaits--'cause\ \[Tk\]\ and\ \[tclsvc\]\ launch\ their\ own.\n\n\[PS\]\ 9Mar04\ For\ example:\ this\ script,\ which\ implements\ a\ TCP\ server\ in\ tclsh\ and\ wish,\ will\ not\ exit\ properly\ when\ you\ close\ its\ main\ window.\n======\n\ proc\ accept\ \{\ channel\ peer\ port\ \}\ \{\n\ \ \ \ close\ \$channel\n\ \}\n\ socket\ -server\ accept\ 5000\n\ vwait\ forever\n\nAfter\ you\ close\ the\ window,\ the\ wish\ app\ does\ not\ exit,\ but\ remains\ fully\ active\ in\ memory.\n\n'''\[DGP\]'''\ Note\ that\ this\ discussion\ is\ essentially\ another\nvote\ in\ favor\ of\ Tk\ Feature\ Request\ 456548\n\[http://sf.net/tracker/?func=detail&aid=456548&group_id=12997&atid=362997\].\n\nThe\ flaw\ here\ is\ in\ Tk's\ continued\ assumptions\ about\ being\ in\ wish,\nrather\ than\ being\ an\ independent\ package\ that\ might\ be\ loaded\ into\ any\ Tcl\ interp.\ \ There's\ nothing\ wrong\ with\ \[\[vwait\]\]\ (at\ least\nnothing\ revealed\ in\ this\ discussion.\ :)\ ).\n----\n\n\[Chris\ Nelson\]\ said\ \[http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/3ebbe18159a8efac?tvc=2&q=multiple+vwaits%|%these\ golden\ words%|%\]\ on\ \[the\ comp.lang.tcl\ newsgroup\]:\n\n''Multiple\ vwaits\ nest,\ they\ do\ not\ happen\ in\ parallel.\ \ The\ outermost\ vwait\ cannot\ complete\ until\ all\ others\ return.''\n\n----\n\n'''vwait\ forever''':\ ''Wish''\ has\ a\ built-in\ event\ loop.\ Tclsh\ has\ one\ too\ but\ enters\ that\ only\ on\ demand,\ for\ which\ the\ \[idiom\]\ is\ to\ write\ at\ the\ end\ of\ code\n======\n\ vwait\ forever\n======\n(''forever''\ being\ the\ name\ of\ a\ variable\ that\ is\ presumably\ never\ used,\ but\ you\ can\ set\ ''forever''\ to\ any\ value\ to\ terminate\ such\ a\ Tcl\ script).\ ''RS''\nSee\ the\ note\ below\ about\ namespaces\ -\ missing\ this\ note\ results\ in\ problems\ that\ occur\ quite\ commonly!\n(See\ the\ note\ below\ about\ namespaces\ -\ missing\ this\ note\ results\ in\ problems\ that\ occur\ quite\ commonly!)\n\n----\n\n'''Timeout\ for\ vwait''':\ Wai\ Shun\ Au\ wrote\ in\ \[the\ comp.lang.tcl\ newsgroup\]:\nafter\ 30000\ \{set\ a\ \$a\}\n\ after\ 30000\ \{set\ a\ \$a\}\n\ vwait\ a\n\n\n\[Jeffrey\ Hobbs\]\ commented:\ \ You\ found\ the\ standard\ way,\ but\ you\ have\ to\ go\ a\n\[Jeffrey\ Hobbs\]\ commented:\nYou\ found\ the\ standard\ way,\ but\ you\ have\ to\ go\ a\ bit\ further\ to\ avoid\ weird\ bugs.\ \ Cache\ the\ \[after\]\ id\ and\ make\ sure\ to\ cancel\ it\ following\ the\ ''vwait''\ (no\ \[catch\]\ needed\ -\ if\ the\ after\ id\ no\ longer\ exists,\ because\ it\ was\ triggered,\ ''after\ cancel''\ doesn't\ care).\ \ That\ way\ you\ won't\ get\ ''a''\ being\ reset\ no\ matter\ what\ in\ 30\ secs.\n----\n\n\[DKF\]:\ \ You\ can\ '''`vwait`\ on\ several\ variables\ simultaneously'''\ as\ long\ as\nYou\ can\ '''\[\[vwait\]\]\ on\ several\ variables\ simultaneously'''\ as\ long\ as\ all\ those\ variables\ are\ in\ the\ same\ array,\ and\ you\ are\ happy\ for\ any\ set\ of\ the\ array\ to\ cause\ the\ \[\[vwait\]\]\ to\ terminate.\ \ Do\ this\ by\ making\ the\ \[\[vwait\]\]\ be\ on\ the\ overall\ array,\ and\ not\ any\ element\ of\ it.\ \ ''\[DKF\]''\n----\n\n\[BBH\]:\ \ Actually,\ you\ can\ combine\ the\ multiple\ variable\ &\ timeout\ nicely\nActually,\ you\ can\ combine\ the\ multiple\ variable\ &\ timeout\ nicely\ without\ the\ variables\ having\ to\ be\ related,\ and\ the\ timer\ won't\ affect\ the\ actual\ variables,\ Demonstrated\ by\ this\ code\ taken\ from\ dissussion\ on\ \[the\ comp.lang.tcl\ newsgroup\]\ (most\ of\ the\ original\ work\ by\ \[Donald\ Porter\],\ that\ I\ tweaked\ a\ little\ to\ add\ timeout\ option).\ ''\[BBH\]''\nkenstir:\ \ I\ have\ further\ tweaked\ this\ version\ of\ waitForAny\ that\ returns\ the\nI\ have\ further\ tweaked\ this\ version\ of\ waitForAny\ that\ returns\ the\ var\ (or\ vars)\ that\ got\ set\ during\ the\ vwait.\ \ This\ allows\ you\ to\ build\ a\ robust\ asynchronous\ queue.\ \ I'm\ submitting\ it\ as\ a\ patch\ to\ tcllib.sourceforge.net\ along\ with\ tests.\ \ ''kenstir''\nnamespace\ eval\ control\ \{\n\ namespace\ eval\ control\ \{\n\ \ \ \ variable\ waitForAnyKey\ 0\n\n\ \ \ \ #\ new\ \"vwait\"\ that\ takes\ multiple\ variables\ and/or\ optional\ timeout\n\ \ \ \ #\ usage:\ \ waitForAny\ ?timeout?\ variable\ ?variable\ ...?\n\ \ \ \ proc\ waitForAny\ \{args\}\ \{\n\ \ \ \ \ \ \ \ variable\ waitForAnyArray\n\ \ \ \ \ \ \ variable\ waitForAnyArray\n\ \ \ \ \ \ \ variable\ waitForAnyKey\n\ \ \ \ \ \ \ \ #\ if\ first\ arg\ is\ a\ number,\ then\ that\ is\ max\ wait\ time\n\ \ \ \ \ \ \ #\ if\ first\ arg\ is\ a\ number,\ then\ that\ is\ max\ wait\ time\n\ \ \ \ \ \ \ if\ \{\[string\ is\ int\ \[lindex\ \$args\ 0\]\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ set\ timeout\ \[lindex\ \$args\ 0\]\n\ \ \ \ \ \ \ \ \ \ set\ args\ \[lrange\ \$args\ 1\ end\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ #\ create\ trigger\ script\ that\ will\ cause\ vwait\ to\ fall\ thru\n\ \ \ \ \ \ \ #\ create\ trigger\ script\ that\ will\ cause\ vwait\ to\ fall\ thru\n\ \ \ \ \ \ \ #\ (trailing\ comment\ is\ to\ eat\ appended\ args\ in\ trace\ command)\n\ \ \ \ \ \ \ set\ index\ \"Key\[incr\ waitForAnyKey\]\"\n\ \ \ \ \ \ \ set\ trigger\ \"\[namespace\ code\ \[list\ set\ waitForAnyArray(\$index)\ 1\]\]\ \;#\"\n\ \ \ \ \ \ \ \ #\ create\ trace\ to\ trip\ trigger\n\ \ \ \ \ \ \ #\ create\ trace\ to\ trip\ trigger\n\ \ \ \ \ \ \ foreach\ var\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ uplevel\ \\#0\ \[list\ trace\ variable\ \$var\ w\ \$trigger\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ #\ set\ timer\ is\ user\ requested\ one\n\ \ \ \ \ \ \ #\ set\ timer\ is\ user\ requested\ one\n\ \ \ \ \ \ \ if\ \{\[info\ exists\ timeout\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ set\ timerId\ \[after\ \$timeout\ \$trigger\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ vwait\ \[namespace\ which\ -variable\ waitForAnyArray\](\$index)\n\ \ \ \ \ \ \ \ #\ remove\ all\ traces\n\ \ \ \ \ \ \ #\ remove\ all\ traces\n\ \ \ \ \ \ \ foreach\ var\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ uplevel\ \\#0\ \[list\ trace\ vdelete\ \$var\ w\ \$trigger\]\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ #\ cancel\ timer\n\ \ \ \ \ \ \ #\ cancel\ timer\n\ \ \ \ \ \ \ if\ \[info\ exists\ timerId\]\ \{\n\ \ \ \ \ \ \ \ \ \ after\ cancel\ \$timerId\n\ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ #\ cleanup\n\ \ \ \ \ \ \ unset\ waitForAnyArray(\$index)\n\}\n\ \}\n\n----\n\n'''vwait\ in\ namespaces:'''\ The\ varName\ must\ be\ globally\ qualified\ as\ if\ in\ a\ binding,\ even\ if\ the\ vwait\ is\ inside\ a\ ''namespace\ eval'':\nnamespace\ eval\ foo\ \{\n\ namespace\ eval\ foo\ \{\n\ \ \ \ \ \ \ vwait\ bar\ \ \ \ \ \ \ \ \;#\ will\ never\ fire\n\ \ \ \ \ \ \ vwait\ ::foo::bar\ \;#\ does\ the\ job\n\ \ \ \ variable\ bar\ \ \ \ \ \;#\ These\ two\ lines\ also\ do\ the\ job\n\ \ \ \ \ \ \ variable\ bar\ \ \ \ \ \;#\ These\ two\ lines\ also\ do\ the\ job\n\ \ \ \ \ \ \ vwait\ \[namespace\ which\ -variable\ bar\]\ \ \ \ \;#\ DGP\n\ \}\ \;#\ RS\n\n----\nA\ majority\ of\ the\ coding\ questions\ received\ in\ \[comp.lang.tcl\]\nA\ majority\ of\ the\ coding\ questions\ received\ in\ \[the\ comp.lang.tcl\ newsgroup\]\ about\ vwait\ appear\ to\ result\ from\ deep\ misunderstandings\ of\ the\ command\ (as\ opposed\ to\ mere\ syntactic\ confusion,\ for\ example).\ \[Bruce\ Hartweg\]\ has\ rightly\ advised\ that\ its\ proper\ use\ is\ restricted:\ \ \"IMHO\ vwaits\ shouldn't\ be\ used\ too\ much\ (the\ nesting\ issue\ creates\ unexpected\ results)\ because\ you\ are\ trying\ to\ force\ a\ synchronous\ approach\nin\ an\ event\ world\ -\ It\ is\ much\ better\ to\ keep\ everything\ event\ driven.\ Occasionally\ for\ simple\ things\ (like\ dialogs)\ to\ use\ a\ vwait\ to\ avoid\ having\ to\ break\ something\ the\ has\ a\ couple\ of\ file\ picks\ and/or\ confirmations\ into\ umpteen\ parts\ has\ its\ place.\"\ \ \[KBK\]\ agrees\ that\ the\ \[Tcl\ event\ loop\]\ is\ widely\ misunderstood\ and\ discusses\ related\ issues\ in\ \[Update\ considered\ harmful\]\ and\ the\ pages\ to\ which\ it\ links.\nin\ an\ event\ world,\ it\ is\ much\ better\ to\ keep\ everything\ event\ driven.\n\nPackages\ such\ as\ \[Tk\]\ and\ \[tclsvc\]\ themselves\ call\ `vwait`.\ \ To\ avoid\ nested\ `vwait`\ calls:\nThis\ little\ program\ demonstrates\ what\ \[Chris\ Nelson\]\ stated\ above\ (vwaits\ nest):\nset\ ::time\ 0\n\ set\ ::time\ 0\n\ set\ ::a\ 0\n\ set\ ::b\ 0\nproc\ a_vwait\ \{\}\ \{\n\ proc\ a_vwait\ \{\ \}\ \{\n\ \ \ \ \ puts\ \"Waiting\ 15\ sec\ for\ ::a\"\n\ \ \ \ \ vwait\ ::a\n\ \ \ \ \ puts\ \"::a\ set\"\n\ \}\nproc\ b_vwait\ \{\}\ \{\n\ proc\ b_vwait\ \{\ \}\ \{\n\ \ \ \ \ puts\ \"Waiting\ 30\ sec\ for\ ::b\"\n\ \ \ \ \ vwait\ ::b\n\ \ \ \ \ puts\ \"::b\ set\"\n\ \}\n\nproc\ timer\ \{\}\ \{\n\ proc\ timer\ \{\ \}\ \{\n\ \ \ \ \ incr\ ::time\ 1\n\ \ \ \ \ puts\ \"\$::time\ sec\"\n\ \ \ \ \ if\ \{\$::time\ ==\ 35\}\ \{\n\ \ \ \ \ \ \ \ \ exit\n\ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ after\ 1000\ timer\n\ \ \ \ \ \}\n\ \}\nafter\ 1\ a_vwait\n\n\ after\ 1\ a_vwait\n\ after\ 5\ b_vwait\n\ after\ 10\ timer\nafter\ 15000\ \{set\ ::a\ 0\}\n\n\ after\ 15000\ \{set\ ::a\ 0\}\n\ after\ 30000\ \{set\ ::b\ 0\}\nvwait\ forever\n\ vwait\ forever\n\n\nWhen\ you\ understand\ this\ code\ snippit,\ you'll\ be\ free\ from\ the\ dangers\ of\ haphazardly\ using\ vwait.\n\n----\n\[Marty\ Backe\]\n15\ August\ 2002\n\n\nChristian\ Klugesherz\ 04\ December\ 2009:\ To\ understand\ what\ really\ happens,\ just\ replace\ the\ above\ timer\ proc,\ by\ adding\ \[after\ info\]\ which\ shows\ the\ existing\ event\ handler\ queue\ \nproc\ timer\ \{\}\ \{\n\ proc\ timer\ \{\ \}\ \{\n\ \ \ \ \ incr\ ::time\ 1\n\ \ \ \ \ puts\ \"\$::time\ sec\"\n\ \ \ \ \ puts\ \[after\ info\]\n\ \ \ \ \ if\ \{\$::time\ ==\ 35\}\ \{\n\ \ \ \ \ \ \ \ \ exit\n\ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ after\ 1000\ timer\n\ \ \ \ \ \ \ \ \ #puts\ \[after\ info\]\n\ \ \ \ \ \}\n\ \}\n\n----\n\nPeter\ Newman\ 9\ March\ 2004:\ '''Wish\ Is\ Buggy!'''\ It\ seems\ to\ me\ that\ all\ these\ problems\ with\ \[vwait\],\ \[tkwait\],\ \[update\]\ and\ ''people\ not\ understanding\ the\ event\ loop'',\ etc\ -\ are\ due\ to\ the\ inherently\ defective\ (in\ my\ opinion\ buggy)\ design\ of\ wish\ -\ in\ that\ it\ automatically\ appends\ the\ event\ loop\ onto\ the\ scripts\ it\ runs.\nPeter\ Newman\ 2004-03-09:\ '''Wish\ Is\ Buggy!'''\ It\ seems\ to\ me\ that\ all\ these\n\n\ pack\ \[button\ .mybutton\ -text\ \"Hello\ World!\"\ -command\ exit\]\ \;\n======\nIt's\ buggy!\ I\ forget\ to\ call\ the\ event\ loop.\ So\ it\ does\ nothing.\ But\ wish\ will\ run\ it\ Ok.\ So\ wish's\ bug\ cancels\ out\ my\ bug\ -\ and\ the\ bug\ in\ my\ program\ gets\ overlooked.\ Almost\ all\ programs\ on\ this\ Wiki\ are\ like\ that.\ As\ written\ by\ the\ programmer,\ there's\ no\ call\ to\ the\ event\ loop.\nNow\ with\ \"Hello\ World\"\ programs\ it\ probably\ doesn't\ matter.\ But\ with\nNow\ with\ \"Hello\ World\"\ programs\ it\ probably\ doesn't\ matter.\ But\ with\ complicated\ real\ world\ programs\ the\ event\ loop\ matters\ a\ lot.\ But\ wish\ permits\ and\ encourages\ Tcl\ programmers\ to\ ignore\ the\ event\ loop.\ We\ only\ worry\ about\ it\ when\ the\ roof\ caves\ in!\ Then\ we\ find\ out\ we\ haven't\ got\ a\ clue\ how\ it\ works.\ Or\ how\ to\ write\ code\ that\ handles\ the\ event\ loop\ properly.\ (Then\ it's\ thank\ God\ for\ pages\ like\ this\ on\ the\ Wiki,\ as\ you\ try\ and\ figure\ it\ out.)\nThe\ solution\ is\ to\ get\ rid\ of\ the\ auto-appending\ the\ event\ loop\ from\ wish.\ And\nThe\ solution\ is\ to\ get\ rid\ of\ the\ auto-appending\ the\ event\ loop\ from\ wish.\ And\ force\ Tcl\ programmers\ to\ learn\ and\ think\ about\ the\ event\ loop\ from\ the\ first,\ and\ with\ every\ subsequent,\ script\ they\ write.\n----\n\n\[schlenk\]\ Not\ really,\ wish\ is\ ok,\ but\ there\ are\ tendencies\ to\ get\ rid\ of\ it\ in\ favor\ of\ tclsh\ and\ package\ require\ Tk.\ Tk\ starts\ the\ event\ loop\ by\ default,\ so\ there\ isn't\ any\ bug.\ If\ you\ use\ Tk,\ you\ have\ a\ running\ event\ loop.\ Why\ make\ things\ more\ complex\ by\ forcing\ people\ to\ require\ the\ event\ loop\ explicitly\ if\ it\ is\ clear\ they\ need\ it?\n\[schlenk\]:\ \ Not\ really,\ wish\ is\ ok,\ but\ there\ are\ tendencies\ to\ get\ rid\ of\ it\n\n\[PS\]\ 9mar04:\ I'd\ have\ to\ agree\ with\ schlenk\ that\ the\ current\ wish\ behaviour\ is\ the\ right\ thing,\ but\ the\ whole\ reason\ I\ moved\ the\ 'check\ for\ tk'\ remark\ to\ the\ top\ of\ the\ page\ is\ that\ I\ was\ bitten\ by\ it\ *again*.\ Currently,\ if\ you\ want\ the\ 'default'\ Tcl\ event\ loop,\ the\ recommended/standard\ way\ seems\ to\ be\ to\ call\ \[\[vwait\ forever\]\].\ But\ there\ are\ more\ and\ more\ script\ out\ there\ that\ run\ in\ multiple\ environments,\ with\ different\ capabilities,\ and\ more\ will\ emerge.\ Is\ checking\ for\ tk\ and\ tclsvr\ enough\ right\ now?\ Probably.\ Will\ it\ be\ in\ the\ future?\ Probably\ not.\ What\ we\ really\ need\ is\ a\ function\ that\ I\ can\ call\ to\ start\ the\ event\ loop,\ which\ -by\ default-\ will\ never\ return.\ Something\ like:\ninterp\ eventloop\n\ interp\ eventloop\n#\ or\ just\n\ #\ or\ just\n\ eventloop\n#\ and\ for\ the\ special\ case\ which\ needs\ it:\n\ #\ and\ for\ the\ special\ case\ which\ needs\ it:\n\{\ ...\ appInitCode\ \}\n\ \{\ ...\ appInitCode\ \}\n\ eventloop\ -pleaseReturnIfPossible\n\ \{\ ...\ appCleanupCode\ \}\n\nOr\ bastardise\ vwait\ to\ do\ the\ same,\ when\ called\ with\ forever\ as\ its\ first\ argument\ (which\ would\ probably\ break\ things).\ And\ maybe\ \[\[interp\ eventloop\ \{script\}\]\]\ to\ provide\ the\ appropriate\ eventloop\ handler\ code.\n\n\[NEM\]\ It\ is\ worth\ pointing\ out\ here\ that\ \[tk_messageBox\]\ calls\ vwait\ internally\ (at\ least\ on\ UNIX).\ This\ has\ been\ a\ cause\ of\ several\ bugs\ in\ event\ driven\ code\ I\ have\ written.\ All\ the\ advice\ given\ on\ this\ page\ about\ not\ calling\ vwait\ should\ also\ apply\ to\ tk_messageBox.\ In\ particular,\ don't\ do\ something\ like\ the\ following:\nfileevent\ \$fd\ readable\ \[list\ readdata\ \$fd\]\n\ fileevent\ \$fd\ readable\ \[list\ readdata\ \$fd\]\n\ proc\ readdata\ \{fd\}\ \{\n\ \ \ \ set\ line\ \[gets\ \$fd\]\n\ \ \ \ #\ Some\ other\ stuff...\n\ \ \ \ tk_messageBox\ ...\n\ \ \ \ #\ Some\ more\ stuff...\n\}\n\ \}\n\nThe\ problem\ is\ that\ the\ internal\ vwait\ means\ that\ your\ readdata\ proc\ will\ likely\ be\ re-entered,\ causing\ all\ kinds\ of\ mayhem\ to\ ensue.\ The\ way\ I\ coded\ around\ this\ was\ to\ implement\ my\ own\ dialog\ box\ code,\ which\ took\ a\ callback:\n======\n\ messagebox\ ...\ -command\ \[list\ dosomething\ ...\]\nBut\ then,\ you\ still\ have\ to\ deal\ with\ what\ to\ do\ with\ events\ that\ come\ in\ while\nBut\ then,\ you\ still\ have\ to\ deal\ with\ what\ to\ do\ with\ events\ that\ come\ in\ while\ the\ dialog\ is\ still\ raised.\ (Do\ you\ process\ them,\ or\ should\ you\ wait\ until\ the\ dialog\ box\ is\ dismissed?)\ I\ never\ really\ decided\ what\ the\ ''correct''\ behaviour\ in\ this\ situation\ would\ be.\n\nIn\ case\ it\ matters\ to\ you,\ this\ quickie\ will\ prevent\ recursive\ \[\[vwait\]\]\ while\ permitting\ iterative\ \[\[vwait\]\]\ -\ \[\[\[CMcC\]\]\]\n======\nrename\ ::vwait\ ::vwait_org\n\ \ \ rename\ ::vwait\ ::vwait_org\n\ \ \ proc\ ::vwait\ \{var\}\ \{\n\ \ \ \ \ \ \ rename\ ::vwait\ ::no_vwait\n\ \ \ \ \ \ \ set\ result\ \[uplevel\ 1\ vwait_org\ \$var\]\n\ \ \ \ \ \ \ rename\ ::no_vwait\ ::vwait\n\ \ \ \ \ \ \ return\ \$result\n\ \ \ \}\n\n\nKen:\ I\ have\ one\ a\ problem\ with\ the\ follow\ code,\ i\ intended\ to\ transfer\ control\ to\ other\ parts\ of\ my\ program\ so\ i\ intend\ embed\ to\ use\ this\ code\ into\ my\ program\ to\ halt\ the\ procession\ of\ one\ function\ and\ go\ to\ other\ function\ which\ would\ call\ it\ again?\ Below\ is\ the\ code\nset\ Flag\ 0\n\ \ \ \ \ \ \ \ \ set\ Flag\ 0\n\ \ \ \ \ \ \ \ \ if\ \{\$Flag\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ continue\n\ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ vwait\ Flag\ \}\n\nbut\ for\ this\ code\ it\ seems\ that\ it\ would\ prompt\ an\ error\ code\ which\ is\ \"can't\n\nbut\ for\ this\ code\ it\ seems\ that\ it\ would\ prompt\ an\ error\ code\ which\ is\ \"can't\ wait\ for\ variable\ Flag\"\ if\ flag\ stays\ at\ 0.\ So\ how\ should\ i\ proceed\ so\ that\ it\ would\ not\ prompt\ this\ error\ code.\n\n<<discussion>>\n\n<<categories>>\ Tcl\ syntax\ help\ |\ Arts\ and\ Crafts\ of\ Tcl-Tk\ Programming\ |\ Command} CALL {my revision vwait} CALL {::oo::Obj2210692 process revision/vwait} CALL {::oo::Obj2210690 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