Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/upvar?V=35
QUERY_STRINGV=35
CONTENT_TYPE
DOCUMENT_URI/revision/upvar
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.58.135
REMOTE_PORT52568
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.143.168.172
HTTP_CF_RAY8801a1df7fe21107-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_CF_CONNECTING_IP3.143.168.172
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 upvar upvar\ -\ Create\ link\ to\ variable\ in\ a\ different\ stack\ frame\n\nhttp://purl.org/tcl/home/man/tcl8.5/TclCmd/upvar.htm\ .\n\n\n\nThis\ command\ arranges\ for\ one\ or\ more\ local\ variables\ in\ the\ current\ procedure\ to\ refer\ to\ variables\ in\ an\ enclosing\ procedure\ call\ or\ to\ global\ variables.\ ''Level''\ may\ have\ any\ of\ the\ forms\ permitted\ for\ the\ '''\[uplevel\]'''\ command,\ and\ may\ be\ omitted\ if\ the\ first\ letter\ of\ the\ first\ ''otherVar''\ isn't\ #\ or\ a\ digit\ (it\ defaults\ to\ 1).\ For\ each\ ''otherVar''\ argument,\ '''upvar'''\ makes\ the\ variable\ by\ that\ name\ in\ the\ procedure\ frame\ given\ by\ ''level''\ (or\ at\ global\ level,\ if\ level\ is\ '''#0''')\ accessible\ in\ the\ current\ procedure\ by\ the\ name\ given\ in\ the\ corresponding\ ''myVar''\ argument.\ The\ variable\ named\ by\ ''otherVar''\ need\ not\ exist\ at\ the\ time\ of\ the\ call\;\ it\ will\ be\ created\ the\ first\ time\ ''myVar''\ is\ referenced,\ just\ like\ an\ ordinary\ variable.\ There\ must\ not\ exist\ a\ variable\ by\ the\ name\ ''myVar''\ at\ the\ time\ '''upvar'''\ is\ invoked.\ ''MyVar''\ is\ always\ treated\ as\ the\ name\ of\ a\ variable,\ not\ an\ array\ element.\ Even\ if\ the\ name\ looks\ like\ an\ array\ element,\ such\ as\ '''a(b)''',\ a\ regular\ variable\ is\ created.\ ''OtherVar''\ may\ refer\ to\ a\ scalar\ variable,\ an\ array,\ or\ an\ array\ element.\ '''Upvar'''\ returns\ an\ empty\ string.\n\nThe\ '''upvar'''\ command\ simplifies\ the\ implementation\ of\ call-by-name\ procedure\ calling\ and\ also\ makes\ it\ easier\ to\ build\ new\ control\ constructs\ as\ Tcl\ procedures.\n`upvar`\ makes\ ''myVar''\ an\ alias\ for\ ''otherVar''.\ ''otherVar''\ can\n**Using\ upvar**\nIt\ is\ an\ error\ for\ ''myVar\ and\ ''otherVar''\ to\ resolve\ to\ the\ same\ name\ unless\n\ \ \ *\ *really*\ try\ to\ avoid\ using\ \[upvar\]\ with\ variable\ names\ not\ passed\ in\ by\ the\ caller\n\n\ \ \ *\ consider\ whether\ \[namespace\ upvar\]\ is\ a\ better\ fit\n\n<<discussion>>\n======\n\[CMcC\]:\ Could\ someone\ write\ about\ what\ happens\ if\ otherVar\ is\ a\ namespace-qualified\ name?\ \ Does\ a\ fully-qualified\ name\ work?\ \ What\ does\ a\ partially-qualified\ name\ do?\ \n\n\[Lars\ H\]:\ Nothing\ special,\ much\;\ these\ variables\ are\ also\ looked\ up\ according\ \nto\ the\ normal\ rules.\ Fully\ qualified\ names\ are\ straightforward.\ \nPartially\ qualified\ names\ are\ relative\ to\ the\ namespace\ of\ the\ specified\ \n''level'',\ but\ the\ tendency\ of\ partially\ qualified\ names\ to\ bind\ to\ existing\ \nvariables\ that\ are\ relative\ to\ the\ ::\ namespace\ can\ produce\ surprising\ \neffects\ that\ may\ obscure\ this.\n\n----\nFrom\ http://www.psg.com/~joem/tcl/faq.html\ I\ see:\n**\ Using\ `\[upvar\]`\ with\ an\ array\ **\nUse\ '''upvar'''\ rather\ than\ try\ to\ use\ '''\[global\]'''\ variables\ when\ possible.\ If\ the\ function\ is\ event\ driven,\ you\ are\ forced\ to\ use\ global\ variables.\n======\n''the\ statement\ \"you\ are\ forced\ to\ use\ global\ variables\"\ is\ a\ bit\ misleading.\ It's\ not\ that\ upvar\ doesn't\ work\ in\ event\ driven\ programs,\ it's\ just\ that\ functions\ called\ from\ events\ are\ run\ at\ the\ global\ level,\ rendering\ upvar\ relatively\ useless.\ If\ you\ have\ a\ callback\ that\ calls\ another\ proc,\ that\ second\ proc\ can\ use\ upvar\ with\ impunity''\n\n\ \ \ \ #\ print\ elements\ of\ an\ array\n\ \ \ \ proc\ show_array\ arrayName\ \{\n\ \ \ \ \ \ \ \ upvar\ \$arrayName\ myArray\n\ \ \ \ foreach\ element\ \[array\ names\ myArray\]\ \{\n\ \ \ \ \ \ \ \ foreach\ element\ \[array\ names\ myArray\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ puts\ stdout\ \"\$\{arrayName\}(\$element)\ =\ \ \$myArray(\$element)\"\n\ \ \ \ \ \ \ \ \}\n\}\nproc\ main\ \{\}\ \{\n\ \ \ \ set\ arval(0)\ zero\n\ \ \ \ set\ arval(1)\ one\n\ \ \ \ show_array\ arval\n======\nTo\ return\ an\ array\ from\ a\ procedures,\ just\ take\ the\ array\ name\ in\ as\ an\ argument,\ as\ above.\ Any\ changes\ you\ make\ in\ the\ array\ will\ be\ made\ in\ the\ parent's\ array\ as\ well.\n\nExtended\ Tcl\ introduces\ a\ concept\ called\ keyed\ lists\ which\ are\ arrays\ made\ out\ of\ lists\ of\ key-value\ pairs\ and\ can\ be\ passed\ by\ value\ to\ routines,\ over\ networks,\ etc.\n\n----\n\[RS\]\ \[upvar\]\ can\ also\ be\ used\ for\ both\ global\ and\ local\ variables:\n\n\ upvar\ #0\ foo\ foo\ \ \;#\ equivalent\ to:\ global\ foo\n\ upvar\ \ 0\ foo\ bar\ \ \;#\ assigns\ alias\ 'bar'\ to\ a\ local\ variable\ 'foo'\nIn\ the\ example\ above,\ any\ changes\ made\ to\ elements\ in\ `\$myArray`\ will\ be\n\[MS\]\ notes\ that\ the\ equivalence\ to\ \[global\]\ is\ '''only\ within\ proc\ bodies''':\ \[global\]\ is\ a\ no-op\ outside\ of\ them,\ '''upvar\ #0'''\ is\ not.\n\n----\nA\ recent\ exchange\ on\ the\ \[AOLserver\]\ mailing\ list\ resulted\ in\ a\ page\ with\ guidelines\ for\ using\ upvar\ and\ \[uplevel\]\ being\ published\ at\ http://dqd.com/~mayoff/notes/tcl/upvar.html\ .\n**\ `upvar`\ prefix*\ for\ Variables\ in\ an\ \[Array\]\ **\n----\nSome\ of\ the\ information\ at\ the\ mentioned\ site\ seems\ to\ be\ incorrect.\ Especially\ in\ reference\ to\ uplevel.\nI\ didn't\ look\ at\ in\ great\ detail\ however.\ Does\ this\ advice\ simply\ reflect\ best\ practice\ or\ what\ can\ be\ done?\n======\n----\n\ #\ Purpose\ -\n\ #\ \ Utility\ to\ turn\ an\ subset\ of\ an\ array\ into\ alias\ upvar'd\ variables\ for\ local\ function\ use.\n\ #\ \ This\ assumes\ the\ array\ is\ defined\ in\ one\ level\ above\ where\ this\ routine\ is\ called.\n\ #\ \ Todo\ -\n\ #\ \ \ allow\ array\ to\ be\ defined\ at\ other\ levels.\n\ #\ \ \ why\ does\ it\ not\ work\ unless\ I\ quote\ \$\{arName\}(ind)\ with\ \{\}\ ??\n\ #\n\ #\ Right\ now\ the\ source\ array\ has\ to\ be\ in\ the\ global\ level\n\ #\n\ proc\ upAr\ \{\ arName\ index\ \}\ \{\n\ \ upvar\ \$arName\ ar\n\ \ foreach\ ind\ \[array\ names\ ar\ \$\{index\}*\]\ \ \{\n\ \ \ regsub\ \$index\ \$ind\ \{\}\ indVar\n\ \ \ if\ \{\ \[info\ level\ \]\ ==\ 1\ \}\ \{\n\ #\ This\ was\ executed\ from\ level\ 0\ \ \n\ \ \ \ uplevel\ 1\ \[list\ upvar\ #0\ \$\{arName\}(\$ind)\ \$indVar\]\n\ \ \ \}\ else\ \{\n\ \ \ \ uplevel\ 1\ \[list\ upvar\ #0\ \$\{arName\}(\$ind)\ \$indVar\]\ \ \n\ \ \ \}\n\ \ \}\n\ \}\n\[Art\ M.\]\n\n----\n\[AMG\]\ I\ like\ that\ ''level''\ is\ optional,\ but\ I\ don't\ like\ the\ method\ used\ to\ identify\ whether\ or\ not\ it\ is\ present.\ \ The\ following\ code\ (an\ in-place\ lsort):\n======\n\ proc\ naive_iplsort\ \{lst\}\ \{\n\ \ \ \ set\ var\ \[lsort\ \$var\]\n\}\n\ \}\nbreaks\ whenever\ `\$lst`\ starts\ with\ `#`\ or\ a\ numeral,\ because\ `\[upvar\]`\ guesses\nbreaks\ whenever\ \$lst\ starts\ with\ #\ or\ a\ numeral,\ since\ \[\[upvar\]\]\ guesses\ that\ its\ first\ parameter\ is\ ''level''\ rather\ than\ ''otherVar''.\n======none\n\ %\ set\ data\ \{4\ 3\ 2\ 1\ 0\}\;\ set\ #0\ \{9\ 8\ 7\ 6\ 5\}\;\ set\ 0a\ \{e\ d\ c\ b\ a\}\n\ %\ naive_iplsort\ data\n\ 0\ 1\ 2\ 3\ 4\n\ %\ naive_iplsort\ #0\n\ wrong\ #\ args:\ should\ be\ \"upvar\ ?level?\ otherVar\ localVar\ ?otherVar\ localVar\ ...?\"\n\ %\ naive_iplsort\ 0a\n\ expected\ integer\ but\ got\ \"0a\"\nThe\ fix\ is\ to\ explicitly\ supply\ ''level'':\nThe\ fix\ is\ explicitly\ supply\ ''level'':\n======\n\ proc\ paranoid_iplsort\ \{lst\}\ \{\n\ \ \ \ set\ var\ \[lsort\ \$var\]\n\}\n\ \}\nThis\ makes\ it\ abundantly\ clear\ to\ Tcl\ that\ `\$lst`\ is\ an\ not\ ''level''\ but\ an\ ''otherVar''\ argument,\ but\ I\ think\ it's\ kind\ of\ painful\ to\ type,\ since\ it\ admits\ that\ Tcl\ has\ the\ feature\ that\ ''level''\ is\ optional,\ but\ that\ feature\ can\ '''never'''\ be\ used\ safely.\ \ At\ least\ it\ works:\nThis\ makes\ it\ abundantly\ clear\ to\ Tcl\ that\ \$lst\ is\ a\ variable\ name\ and\ not\ a\ level.\ \ But\ I\ think\ it's\ kind\ of\ painful\ to\ type,\ since\ it\ admits\ that\ Tcl\ has\ a\ feature\ (''level''\ is\ optional)\ that\ can\ '''never'''\ be\ used\ safely.\ \ At\ least\ it\ works:\n======none\n\ %\ set\ data\ \{4\ 3\ 2\ 1\ 0\}\;\ set\ #0\ \{9\ 8\ 7\ 6\ 5\}\;\ set\ 0a\ \{e\ d\ c\ b\ a\}\n\ %\ paranoid_iplsort\ data\n\ 0\ 1\ 2\ 3\ 4\n\ %\ paranoid_iplsort\ #0\n\ 5\ 6\ 7\ 8\ 9\n\ %\ paranoid_iplsort\ 0a\n\ a\ b\ c\ d\ e\nI\ know\ it\ may\ be\ a\ bit\ too\ late\ to\ change\ this,\ but\ I'd\ prefer\ that\ `\[upvar\]`\nI\ know\ it\ may\ be\ a\ bit\ too\ late\ to\ change\ this,\ but\ I'd\ prefer\ that\ \[\[upvar\]\]\ use\ a\ different\ algorithm\ to\ determine\ whether\ its\ first\ argument\ is\ ''level''\ or\ ''otherVar''.\ \ I'll\ explain\ by\ way\ of\ demonstration:\n======\n\ rename\ upvar\ Upvar\n\ proc\ upvar\ \{args\}\ \{\n\ \ \ \ \ \ \ \ \ #\ Received\ zero\ arguments.\n\ \ \ \ \ \ \ #\ Received\ zero\ arguments.\n\ \ \ \ \ \ \ #\ Allow\ \[upvar\]\ to\ raise\ an\ error.\n\ \ \ \ \ \ \ \ \ #\ Received\ an\ even\ number\ of\ arguments.\n\ \ \ \ \ \ \ #\ Received\ an\ even\ number\ of\ arguments.\n\ \ \ \ \ \ \ #\ Conclude\ that\ the\ first\ is\ a\ variable\ name.\n\ \ \ \ \ \ \ #\ Prepend\ \$args\ with\ the\ default\ level,\ 1.\n\ \ \ \ \ \ \ set\ args\ \[linsert\ \$args\ 0\ 1\]\n\ \ \ \ \ \ \ \ \ #\ Received\ an\ odd\ number\ of\ arguments.\n\ \ \ \ \ \ \ #\ Received\ an\ odd\ number\ of\ arguments.\n\ \ \ \ \ \ \ #\ Conclude\ that\ the\ first\ is\ a\ level\ number.\n\n\ \ \ \ #\ Let\ the\ real\ \[upvar\]\ do\ its\ thing.\n\ \ \ \ uplevel\ 1\ Upvar\ \$args\n\}\n\ \}\nAnd\ a\ test:\n\n======\n\ %\ upvar\ 0\ 0a\ alpha\n\ %\ set\ 0a\ success\;\ puts\ \$alpha\n\ success\n\ %\ proc\ test\ \{\}\ \{upvar\ 0a\ beta\;\ puts\ \$beta\}\n\ %\ test\n\ success\nThis\ should\ also\ work\ in\ the\ case\ of\ multiple\ variable\ pairs.\n\nIronically,\ I\ use\ `\[uplevel\]\ 1`\ in\ the\ above\ code.\ \ `\[uplevel\]`\ has\ a\ similar\nIronically,\ I\ use\ \[\[uplevel\ 1\]\]\ in\ the\ above\ code.\ \ \[\[\[uplevel\]\]\]\ has\ a\ similar\ problem---\ \"Level\ cannot\ be\ defaulted\ if\ the\ first\ command\ argument\ starts\ with\ a\ digit\ or\ #.\"\ \ But\ there's\ no\ possibility\ of\ a\ cutesy\ workaround\ wrapper\ because\ it\ can\ legally\ accept\ ''any''\ number\ of\ arguments,\ whereas\ ''upvar''\ can\ only\ take\ an\ even\ number\ (not\ counting\ ''level'').\nSo\ perhaps\ for\ the\ sake\ of\ consistency\ with\ `\[uplevel\]`\ I\ should\ just\ go\ ahead\nSo\ perhaps\ for\ the\ sake\ of\ consistency\ with\ \[\[uplevel\]\]\ I\ should\ just\ go\ ahead\ and\ put\ those\ blasted\ 1's\ in\ there\ anyway.\ :^)\n\n----\n\[IL\]\ I'm\ curious\ about\ the\ performance\ implications\ of\ upvar\ recently.\ \ Is\ there\ a\ page\ discussing\ them?\ \ Passing\ a\ list\ vs.\ upvaring\ it\ for\ example.\ \ I\ had\ always\ assumed\ that\ any\ pass\ in\ TCL\ was\ by\ reference,\ unless\ upvar\ is\ exactly\ that\ and\ everything\ else\ is\ by\ value?\n\n\[RS\]:\ The\ Tcl\ way\ is\ indeed\ normally\ passing\ by\ value,\ which\ helps\ to\ make\ the\ code\ more\ robust\ (no\ side-effects\ possible).\ ''upvar''\ is\ the\ way\ to\ pass\ by\ reference.\ The\ difference\ appears\ to\ be\ very\ little\ (or\ 50%\ more,\ if\ you\ take\ the\ Win\ XP\ timing\ to\ be\ precise):\n\ proc\ a\ x\ \{\n\}\n\ \}\n\ proc\ b\ _x\ \{\n\ \ \ \ expr\ \{\$x*\$x\}\n\}\n\ \}\n\ %\ time\ \{set\ x\ 42\;\ a\ \$x\}\ 100000\n\ 2\ microseconds\ per\ iteration\n\ %\ time\ \{set\ x\ 42\;\ b\ x\}\ 100000\n\ 3\ microseconds\ per\ iteration\n\[PYK\]\ 2014-08-14:\ Coming\ to\ Tcl\ from\ other\ language\ traditions,\ one\ of\ the\n\[Lars\ H\],\ 2008-08-21:\ When\ implementing\ the\ ''Man\ or\ Boy\ test''\ \[http://en.wikipedia.org/wiki/Wikipedia_talk:Articles_for_creation/Submissions/Man_or_boy_test_implementations#Tcl\]\ in\ Tcl\ a\ while\ back,\ I\ was\ surprised\ to\ see\ that\ the\ implementation\ using\ '''upvar'''\n======\nproc\ A\ \{k\ x1\ x2\ x3\ x4\ x5\}\ \{\n\ \ \ \ expr\ \{\$k<=0\ ?\ \[eval\ \$x4\]+\[eval\ \$x5\]\ :\ \[B\ \\#\[info\ level\]\]\}\n\}\nproc\ B\ \{level\}\ \{\n\ \ \ \ upvar\ \$level\ k\ k\ x1\ x1\ x2\ x2\ x3\ x3\ x4\ x4\n\ \ \ \ incr\ k\ -1\n\ \ \ \ A\ \$k\ \[info\ level\ 0\]\ \$x1\ \$x2\ \$x3\ \$x4\n\}\nproc\ C\ \{val\}\ \{return\ \$val\}\ninterp\ recursionlimit\ \{\}\ 1157\nA\ 10\ \{C\ 1\}\ \{C\ -1\}\ \{C\ -1\}\ \{C\ 1\}\ \{C\ 0\}\n======\n\nwas\ actually\ about\ 30%\ faster\ than\ the\ \"purer\"\ implementation\ passing\ as\ much\nwas\ actually\ about\ 30%\ faster\ than\ the\ \"purer\"\ implementation\ passing\ as\ much\ as\ possible\ by\ value\ (and\ using\ '''uplevel'''\ for\ the\ side-effect\ required\ by\ the\ test):\n======\nproc\ AP\ \{k\ x1\ x2\ x3\ x4\ x5\}\ \{expr\ \{\$k<=0\ ?\ \[eval\ \$x4\]+\[eval\ \$x5\]\ :\ \[BP\ \\#\[info\ level\]\ \$x1\ \$x2\ \$x3\ \$x4\]\}\}\nproc\ BP\ \{level\ x1\ x2\ x3\ x4\}\ \{AP\ \[uplevel\ \$level\ \{incr\ k\ -1\}\]\ \[info\ level\ 0\]\ \$x1\ \$x2\ \$x3\ \$x4\}\nproc\ C\ \{val\}\ \{return\ \$val\}\ninterp\ recursionlimit\ \{\}\ 1157\nAP\ 10\ \{C\ 1\}\ \{C\ -1\}\ \{C\ -1\}\ \{C\ 1\}\ \{C\ 0\}\n======\n\nThis\ is\ probably\ due\ to\ dragging\ along\ more\ data\ in\ the\ latter\ case.\ (I\ doubt\nThis\ is\ probably\ due\ to\ dragging\ along\ more\ data\ in\ the\ latter\ case.\ (I\ doubt\ it\ is\ a\ \[shimmering\]\ effect,\ since\ failure\ to\ share\ \[Tcl_Obj\]s\ should\ lead\ to\ an\ exponential\ overhead.)\n\n\n\[ZB\]\ In\ the\ docs\ upvar\ page\ there\ is\ a\ remark:\ \"The\ variable\ named\ by\ otherVar\ need\ not\ exist\ at\ the\ time\ of\ the\ call\;\ it\ will\ be\ created\ the\ first\ time\ myVar\ is\ referenced,\ just\ like\ an\ ordinary\ variable\".\ OK,\ so\ let's\ try\ following\ short\ example,\ also\ taken\ from\ the\ docs\ (\"proc\ add2\ name\ \{\ upvar\ \$name\ x\ \;\ set\ x\ \[\[expr\ \{\$x\ +\ 2\}\]\]\ \}\"):\n\[ZB\]:\ According\ to\ the\ documentation,\n\ %\ proc\ add2\ name\ \{\ upvar\ \$name\ x\ \;\ set\ x\ \[expr\ \{\$x\ +\ 2\}\]\ \}\n\ %\ add2\ b\n\ can't\ read\ \"x\":\ no\ such\ variable\n\ %\ puts\ \$b\n\ can't\ read\ \"b\":\ no\ such\ variable\n\ %\ \nIsn't\ it\ contrary\ to\ that\ remark\ \"the\ variable\ doesn't\ need\ to\ exist,\ it\ will\nIsn't\ it\ contrary\ to\ that\ remark\ \"the\ variable\ doesn't\ need\ to\ exist,\ it'll\ be\ created\"?\ The\ \"b\"\ variable\ hasn't\ been\ created.\ Pay\ attention,\ that\ variable\ myVar\ (\"x\"\ in\ example\ above)\ '''has\ been\ referenced'''.\ Although\ I\ agree,\ that\ it\ looks\ like:\ \"take\ something\ non-existing,\ and\ add\ a\ value\ of\ 2\ to\ this\"\ -\ but\ still:\ variable\ x\ has\ been\ referenced.\n\[PYK\]\ 2014-03-24:\ \ A\ variable\ can\ be\ created\ but\ not\ defined.\ \ `upvar`\ creates\n<<discussion>>\n======\n----\n!!!!!!\n\[\[\n\[Tcl\ syntax\ help\]\ |\n\[Arts\ and\ Crafts\ of\ Tcl-Tk\ Programming\]\n\]\]\n\n%|\ \[Category\ Command\]\ |\ \[Category\ Introspection\]\ |\ \[Category\ Control\ Structure\]\ |%\n!!!!!! regexp2} CALL {my render upvar upvar\ -\ Create\ link\ to\ variable\ in\ a\ different\ stack\ frame\n\nhttp://purl.org/tcl/home/man/tcl8.5/TclCmd/upvar.htm\ .\n\n\n\nThis\ command\ arranges\ for\ one\ or\ more\ local\ variables\ in\ the\ current\ procedure\ to\ refer\ to\ variables\ in\ an\ enclosing\ procedure\ call\ or\ to\ global\ variables.\ ''Level''\ may\ have\ any\ of\ the\ forms\ permitted\ for\ the\ '''\[uplevel\]'''\ command,\ and\ may\ be\ omitted\ if\ the\ first\ letter\ of\ the\ first\ ''otherVar''\ isn't\ #\ or\ a\ digit\ (it\ defaults\ to\ 1).\ For\ each\ ''otherVar''\ argument,\ '''upvar'''\ makes\ the\ variable\ by\ that\ name\ in\ the\ procedure\ frame\ given\ by\ ''level''\ (or\ at\ global\ level,\ if\ level\ is\ '''#0''')\ accessible\ in\ the\ current\ procedure\ by\ the\ name\ given\ in\ the\ corresponding\ ''myVar''\ argument.\ The\ variable\ named\ by\ ''otherVar''\ need\ not\ exist\ at\ the\ time\ of\ the\ call\;\ it\ will\ be\ created\ the\ first\ time\ ''myVar''\ is\ referenced,\ just\ like\ an\ ordinary\ variable.\ There\ must\ not\ exist\ a\ variable\ by\ the\ name\ ''myVar''\ at\ the\ time\ '''upvar'''\ is\ invoked.\ ''MyVar''\ is\ always\ treated\ as\ the\ name\ of\ a\ variable,\ not\ an\ array\ element.\ Even\ if\ the\ name\ looks\ like\ an\ array\ element,\ such\ as\ '''a(b)''',\ a\ regular\ variable\ is\ created.\ ''OtherVar''\ may\ refer\ to\ a\ scalar\ variable,\ an\ array,\ or\ an\ array\ element.\ '''Upvar'''\ returns\ an\ empty\ string.\n\nThe\ '''upvar'''\ command\ simplifies\ the\ implementation\ of\ call-by-name\ procedure\ calling\ and\ also\ makes\ it\ easier\ to\ build\ new\ control\ constructs\ as\ Tcl\ procedures.\n`upvar`\ makes\ ''myVar''\ an\ alias\ for\ ''otherVar''.\ ''otherVar''\ can\n**Using\ upvar**\nIt\ is\ an\ error\ for\ ''myVar\ and\ ''otherVar''\ to\ resolve\ to\ the\ same\ name\ unless\n\ \ \ *\ *really*\ try\ to\ avoid\ using\ \[upvar\]\ with\ variable\ names\ not\ passed\ in\ by\ the\ caller\n\n\ \ \ *\ consider\ whether\ \[namespace\ upvar\]\ is\ a\ better\ fit\n\n<<discussion>>\n======\n\[CMcC\]:\ Could\ someone\ write\ about\ what\ happens\ if\ otherVar\ is\ a\ namespace-qualified\ name?\ \ Does\ a\ fully-qualified\ name\ work?\ \ What\ does\ a\ partially-qualified\ name\ do?\ \n\n\[Lars\ H\]:\ Nothing\ special,\ much\;\ these\ variables\ are\ also\ looked\ up\ according\ \nto\ the\ normal\ rules.\ Fully\ qualified\ names\ are\ straightforward.\ \nPartially\ qualified\ names\ are\ relative\ to\ the\ namespace\ of\ the\ specified\ \n''level'',\ but\ the\ tendency\ of\ partially\ qualified\ names\ to\ bind\ to\ existing\ \nvariables\ that\ are\ relative\ to\ the\ ::\ namespace\ can\ produce\ surprising\ \neffects\ that\ may\ obscure\ this.\n\n----\nFrom\ http://www.psg.com/~joem/tcl/faq.html\ I\ see:\n**\ Using\ `\[upvar\]`\ with\ an\ array\ **\nUse\ '''upvar'''\ rather\ than\ try\ to\ use\ '''\[global\]'''\ variables\ when\ possible.\ If\ the\ function\ is\ event\ driven,\ you\ are\ forced\ to\ use\ global\ variables.\n======\n''the\ statement\ \"you\ are\ forced\ to\ use\ global\ variables\"\ is\ a\ bit\ misleading.\ It's\ not\ that\ upvar\ doesn't\ work\ in\ event\ driven\ programs,\ it's\ just\ that\ functions\ called\ from\ events\ are\ run\ at\ the\ global\ level,\ rendering\ upvar\ relatively\ useless.\ If\ you\ have\ a\ callback\ that\ calls\ another\ proc,\ that\ second\ proc\ can\ use\ upvar\ with\ impunity''\n\n\ \ \ \ #\ print\ elements\ of\ an\ array\n\ \ \ \ proc\ show_array\ arrayName\ \{\n\ \ \ \ \ \ \ \ upvar\ \$arrayName\ myArray\n\ \ \ \ foreach\ element\ \[array\ names\ myArray\]\ \{\n\ \ \ \ \ \ \ \ foreach\ element\ \[array\ names\ myArray\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ puts\ stdout\ \"\$\{arrayName\}(\$element)\ =\ \ \$myArray(\$element)\"\n\ \ \ \ \ \ \ \ \}\n\}\nproc\ main\ \{\}\ \{\n\ \ \ \ set\ arval(0)\ zero\n\ \ \ \ set\ arval(1)\ one\n\ \ \ \ show_array\ arval\n======\nTo\ return\ an\ array\ from\ a\ procedures,\ just\ take\ the\ array\ name\ in\ as\ an\ argument,\ as\ above.\ Any\ changes\ you\ make\ in\ the\ array\ will\ be\ made\ in\ the\ parent's\ array\ as\ well.\n\nExtended\ Tcl\ introduces\ a\ concept\ called\ keyed\ lists\ which\ are\ arrays\ made\ out\ of\ lists\ of\ key-value\ pairs\ and\ can\ be\ passed\ by\ value\ to\ routines,\ over\ networks,\ etc.\n\n----\n\[RS\]\ \[upvar\]\ can\ also\ be\ used\ for\ both\ global\ and\ local\ variables:\n\n\ upvar\ #0\ foo\ foo\ \ \;#\ equivalent\ to:\ global\ foo\n\ upvar\ \ 0\ foo\ bar\ \ \;#\ assigns\ alias\ 'bar'\ to\ a\ local\ variable\ 'foo'\nIn\ the\ example\ above,\ any\ changes\ made\ to\ elements\ in\ `\$myArray`\ will\ be\n\[MS\]\ notes\ that\ the\ equivalence\ to\ \[global\]\ is\ '''only\ within\ proc\ bodies''':\ \[global\]\ is\ a\ no-op\ outside\ of\ them,\ '''upvar\ #0'''\ is\ not.\n\n----\nA\ recent\ exchange\ on\ the\ \[AOLserver\]\ mailing\ list\ resulted\ in\ a\ page\ with\ guidelines\ for\ using\ upvar\ and\ \[uplevel\]\ being\ published\ at\ http://dqd.com/~mayoff/notes/tcl/upvar.html\ .\n**\ `upvar`\ prefix*\ for\ Variables\ in\ an\ \[Array\]\ **\n----\nSome\ of\ the\ information\ at\ the\ mentioned\ site\ seems\ to\ be\ incorrect.\ Especially\ in\ reference\ to\ uplevel.\nI\ didn't\ look\ at\ in\ great\ detail\ however.\ Does\ this\ advice\ simply\ reflect\ best\ practice\ or\ what\ can\ be\ done?\n======\n----\n\ #\ Purpose\ -\n\ #\ \ Utility\ to\ turn\ an\ subset\ of\ an\ array\ into\ alias\ upvar'd\ variables\ for\ local\ function\ use.\n\ #\ \ This\ assumes\ the\ array\ is\ defined\ in\ one\ level\ above\ where\ this\ routine\ is\ called.\n\ #\ \ Todo\ -\n\ #\ \ \ allow\ array\ to\ be\ defined\ at\ other\ levels.\n\ #\ \ \ why\ does\ it\ not\ work\ unless\ I\ quote\ \$\{arName\}(ind)\ with\ \{\}\ ??\n\ #\n\ #\ Right\ now\ the\ source\ array\ has\ to\ be\ in\ the\ global\ level\n\ #\n\ proc\ upAr\ \{\ arName\ index\ \}\ \{\n\ \ upvar\ \$arName\ ar\n\ \ foreach\ ind\ \[array\ names\ ar\ \$\{index\}*\]\ \ \{\n\ \ \ regsub\ \$index\ \$ind\ \{\}\ indVar\n\ \ \ if\ \{\ \[info\ level\ \]\ ==\ 1\ \}\ \{\n\ #\ This\ was\ executed\ from\ level\ 0\ \ \n\ \ \ \ uplevel\ 1\ \[list\ upvar\ #0\ \$\{arName\}(\$ind)\ \$indVar\]\n\ \ \ \}\ else\ \{\n\ \ \ \ uplevel\ 1\ \[list\ upvar\ #0\ \$\{arName\}(\$ind)\ \$indVar\]\ \ \n\ \ \ \}\n\ \ \}\n\ \}\n\[Art\ M.\]\n\n----\n\[AMG\]\ I\ like\ that\ ''level''\ is\ optional,\ but\ I\ don't\ like\ the\ method\ used\ to\ identify\ whether\ or\ not\ it\ is\ present.\ \ The\ following\ code\ (an\ in-place\ lsort):\n======\n\ proc\ naive_iplsort\ \{lst\}\ \{\n\ \ \ \ set\ var\ \[lsort\ \$var\]\n\}\n\ \}\nbreaks\ whenever\ `\$lst`\ starts\ with\ `#`\ or\ a\ numeral,\ because\ `\[upvar\]`\ guesses\nbreaks\ whenever\ \$lst\ starts\ with\ #\ or\ a\ numeral,\ since\ \[\[upvar\]\]\ guesses\ that\ its\ first\ parameter\ is\ ''level''\ rather\ than\ ''otherVar''.\n======none\n\ %\ set\ data\ \{4\ 3\ 2\ 1\ 0\}\;\ set\ #0\ \{9\ 8\ 7\ 6\ 5\}\;\ set\ 0a\ \{e\ d\ c\ b\ a\}\n\ %\ naive_iplsort\ data\n\ 0\ 1\ 2\ 3\ 4\n\ %\ naive_iplsort\ #0\n\ wrong\ #\ args:\ should\ be\ \"upvar\ ?level?\ otherVar\ localVar\ ?otherVar\ localVar\ ...?\"\n\ %\ naive_iplsort\ 0a\n\ expected\ integer\ but\ got\ \"0a\"\nThe\ fix\ is\ to\ explicitly\ supply\ ''level'':\nThe\ fix\ is\ explicitly\ supply\ ''level'':\n======\n\ proc\ paranoid_iplsort\ \{lst\}\ \{\n\ \ \ \ set\ var\ \[lsort\ \$var\]\n\}\n\ \}\nThis\ makes\ it\ abundantly\ clear\ to\ Tcl\ that\ `\$lst`\ is\ an\ not\ ''level''\ but\ an\ ''otherVar''\ argument,\ but\ I\ think\ it's\ kind\ of\ painful\ to\ type,\ since\ it\ admits\ that\ Tcl\ has\ the\ feature\ that\ ''level''\ is\ optional,\ but\ that\ feature\ can\ '''never'''\ be\ used\ safely.\ \ At\ least\ it\ works:\nThis\ makes\ it\ abundantly\ clear\ to\ Tcl\ that\ \$lst\ is\ a\ variable\ name\ and\ not\ a\ level.\ \ But\ I\ think\ it's\ kind\ of\ painful\ to\ type,\ since\ it\ admits\ that\ Tcl\ has\ a\ feature\ (''level''\ is\ optional)\ that\ can\ '''never'''\ be\ used\ safely.\ \ At\ least\ it\ works:\n======none\n\ %\ set\ data\ \{4\ 3\ 2\ 1\ 0\}\;\ set\ #0\ \{9\ 8\ 7\ 6\ 5\}\;\ set\ 0a\ \{e\ d\ c\ b\ a\}\n\ %\ paranoid_iplsort\ data\n\ 0\ 1\ 2\ 3\ 4\n\ %\ paranoid_iplsort\ #0\n\ 5\ 6\ 7\ 8\ 9\n\ %\ paranoid_iplsort\ 0a\n\ a\ b\ c\ d\ e\nI\ know\ it\ may\ be\ a\ bit\ too\ late\ to\ change\ this,\ but\ I'd\ prefer\ that\ `\[upvar\]`\nI\ know\ it\ may\ be\ a\ bit\ too\ late\ to\ change\ this,\ but\ I'd\ prefer\ that\ \[\[upvar\]\]\ use\ a\ different\ algorithm\ to\ determine\ whether\ its\ first\ argument\ is\ ''level''\ or\ ''otherVar''.\ \ I'll\ explain\ by\ way\ of\ demonstration:\n======\n\ rename\ upvar\ Upvar\n\ proc\ upvar\ \{args\}\ \{\n\ \ \ \ \ \ \ \ \ #\ Received\ zero\ arguments.\n\ \ \ \ \ \ \ #\ Received\ zero\ arguments.\n\ \ \ \ \ \ \ #\ Allow\ \[upvar\]\ to\ raise\ an\ error.\n\ \ \ \ \ \ \ \ \ #\ Received\ an\ even\ number\ of\ arguments.\n\ \ \ \ \ \ \ #\ Received\ an\ even\ number\ of\ arguments.\n\ \ \ \ \ \ \ #\ Conclude\ that\ the\ first\ is\ a\ variable\ name.\n\ \ \ \ \ \ \ #\ Prepend\ \$args\ with\ the\ default\ level,\ 1.\n\ \ \ \ \ \ \ set\ args\ \[linsert\ \$args\ 0\ 1\]\n\ \ \ \ \ \ \ \ \ #\ Received\ an\ odd\ number\ of\ arguments.\n\ \ \ \ \ \ \ #\ Received\ an\ odd\ number\ of\ arguments.\n\ \ \ \ \ \ \ #\ Conclude\ that\ the\ first\ is\ a\ level\ number.\n\n\ \ \ \ #\ Let\ the\ real\ \[upvar\]\ do\ its\ thing.\n\ \ \ \ uplevel\ 1\ Upvar\ \$args\n\}\n\ \}\nAnd\ a\ test:\n\n======\n\ %\ upvar\ 0\ 0a\ alpha\n\ %\ set\ 0a\ success\;\ puts\ \$alpha\n\ success\n\ %\ proc\ test\ \{\}\ \{upvar\ 0a\ beta\;\ puts\ \$beta\}\n\ %\ test\n\ success\nThis\ should\ also\ work\ in\ the\ case\ of\ multiple\ variable\ pairs.\n\nIronically,\ I\ use\ `\[uplevel\]\ 1`\ in\ the\ above\ code.\ \ `\[uplevel\]`\ has\ a\ similar\nIronically,\ I\ use\ \[\[uplevel\ 1\]\]\ in\ the\ above\ code.\ \ \[\[\[uplevel\]\]\]\ has\ a\ similar\ problem---\ \"Level\ cannot\ be\ defaulted\ if\ the\ first\ command\ argument\ starts\ with\ a\ digit\ or\ #.\"\ \ But\ there's\ no\ possibility\ of\ a\ cutesy\ workaround\ wrapper\ because\ it\ can\ legally\ accept\ ''any''\ number\ of\ arguments,\ whereas\ ''upvar''\ can\ only\ take\ an\ even\ number\ (not\ counting\ ''level'').\nSo\ perhaps\ for\ the\ sake\ of\ consistency\ with\ `\[uplevel\]`\ I\ should\ just\ go\ ahead\nSo\ perhaps\ for\ the\ sake\ of\ consistency\ with\ \[\[uplevel\]\]\ I\ should\ just\ go\ ahead\ and\ put\ those\ blasted\ 1's\ in\ there\ anyway.\ :^)\n\n----\n\[IL\]\ I'm\ curious\ about\ the\ performance\ implications\ of\ upvar\ recently.\ \ Is\ there\ a\ page\ discussing\ them?\ \ Passing\ a\ list\ vs.\ upvaring\ it\ for\ example.\ \ I\ had\ always\ assumed\ that\ any\ pass\ in\ TCL\ was\ by\ reference,\ unless\ upvar\ is\ exactly\ that\ and\ everything\ else\ is\ by\ value?\n\n\[RS\]:\ The\ Tcl\ way\ is\ indeed\ normally\ passing\ by\ value,\ which\ helps\ to\ make\ the\ code\ more\ robust\ (no\ side-effects\ possible).\ ''upvar''\ is\ the\ way\ to\ pass\ by\ reference.\ The\ difference\ appears\ to\ be\ very\ little\ (or\ 50%\ more,\ if\ you\ take\ the\ Win\ XP\ timing\ to\ be\ precise):\n\ proc\ a\ x\ \{\n\}\n\ \}\n\ proc\ b\ _x\ \{\n\ \ \ \ expr\ \{\$x*\$x\}\n\}\n\ \}\n\ %\ time\ \{set\ x\ 42\;\ a\ \$x\}\ 100000\n\ 2\ microseconds\ per\ iteration\n\ %\ time\ \{set\ x\ 42\;\ b\ x\}\ 100000\n\ 3\ microseconds\ per\ iteration\n\[PYK\]\ 2014-08-14:\ Coming\ to\ Tcl\ from\ other\ language\ traditions,\ one\ of\ the\n\[Lars\ H\],\ 2008-08-21:\ When\ implementing\ the\ ''Man\ or\ Boy\ test''\ \[http://en.wikipedia.org/wiki/Wikipedia_talk:Articles_for_creation/Submissions/Man_or_boy_test_implementations#Tcl\]\ in\ Tcl\ a\ while\ back,\ I\ was\ surprised\ to\ see\ that\ the\ implementation\ using\ '''upvar'''\n======\nproc\ A\ \{k\ x1\ x2\ x3\ x4\ x5\}\ \{\n\ \ \ \ expr\ \{\$k<=0\ ?\ \[eval\ \$x4\]+\[eval\ \$x5\]\ :\ \[B\ \\#\[info\ level\]\]\}\n\}\nproc\ B\ \{level\}\ \{\n\ \ \ \ upvar\ \$level\ k\ k\ x1\ x1\ x2\ x2\ x3\ x3\ x4\ x4\n\ \ \ \ incr\ k\ -1\n\ \ \ \ A\ \$k\ \[info\ level\ 0\]\ \$x1\ \$x2\ \$x3\ \$x4\n\}\nproc\ C\ \{val\}\ \{return\ \$val\}\ninterp\ recursionlimit\ \{\}\ 1157\nA\ 10\ \{C\ 1\}\ \{C\ -1\}\ \{C\ -1\}\ \{C\ 1\}\ \{C\ 0\}\n======\n\nwas\ actually\ about\ 30%\ faster\ than\ the\ \"purer\"\ implementation\ passing\ as\ much\nwas\ actually\ about\ 30%\ faster\ than\ the\ \"purer\"\ implementation\ passing\ as\ much\ as\ possible\ by\ value\ (and\ using\ '''uplevel'''\ for\ the\ side-effect\ required\ by\ the\ test):\n======\nproc\ AP\ \{k\ x1\ x2\ x3\ x4\ x5\}\ \{expr\ \{\$k<=0\ ?\ \[eval\ \$x4\]+\[eval\ \$x5\]\ :\ \[BP\ \\#\[info\ level\]\ \$x1\ \$x2\ \$x3\ \$x4\]\}\}\nproc\ BP\ \{level\ x1\ x2\ x3\ x4\}\ \{AP\ \[uplevel\ \$level\ \{incr\ k\ -1\}\]\ \[info\ level\ 0\]\ \$x1\ \$x2\ \$x3\ \$x4\}\nproc\ C\ \{val\}\ \{return\ \$val\}\ninterp\ recursionlimit\ \{\}\ 1157\nAP\ 10\ \{C\ 1\}\ \{C\ -1\}\ \{C\ -1\}\ \{C\ 1\}\ \{C\ 0\}\n======\n\nThis\ is\ probably\ due\ to\ dragging\ along\ more\ data\ in\ the\ latter\ case.\ (I\ doubt\nThis\ is\ probably\ due\ to\ dragging\ along\ more\ data\ in\ the\ latter\ case.\ (I\ doubt\ it\ is\ a\ \[shimmering\]\ effect,\ since\ failure\ to\ share\ \[Tcl_Obj\]s\ should\ lead\ to\ an\ exponential\ overhead.)\n\n\n\[ZB\]\ In\ the\ docs\ upvar\ page\ there\ is\ a\ remark:\ \"The\ variable\ named\ by\ otherVar\ need\ not\ exist\ at\ the\ time\ of\ the\ call\;\ it\ will\ be\ created\ the\ first\ time\ myVar\ is\ referenced,\ just\ like\ an\ ordinary\ variable\".\ OK,\ so\ let's\ try\ following\ short\ example,\ also\ taken\ from\ the\ docs\ (\"proc\ add2\ name\ \{\ upvar\ \$name\ x\ \;\ set\ x\ \[\[expr\ \{\$x\ +\ 2\}\]\]\ \}\"):\n\[ZB\]:\ According\ to\ the\ documentation,\n\ %\ proc\ add2\ name\ \{\ upvar\ \$name\ x\ \;\ set\ x\ \[expr\ \{\$x\ +\ 2\}\]\ \}\n\ %\ add2\ b\n\ can't\ read\ \"x\":\ no\ such\ variable\n\ %\ puts\ \$b\n\ can't\ read\ \"b\":\ no\ such\ variable\n\ %\ \nIsn't\ it\ contrary\ to\ that\ remark\ \"the\ variable\ doesn't\ need\ to\ exist,\ it\ will\nIsn't\ it\ contrary\ to\ that\ remark\ \"the\ variable\ doesn't\ need\ to\ exist,\ it'll\ be\ created\"?\ The\ \"b\"\ variable\ hasn't\ been\ created.\ Pay\ attention,\ that\ variable\ myVar\ (\"x\"\ in\ example\ above)\ '''has\ been\ referenced'''.\ Although\ I\ agree,\ that\ it\ looks\ like:\ \"take\ something\ non-existing,\ and\ add\ a\ value\ of\ 2\ to\ this\"\ -\ but\ still:\ variable\ x\ has\ been\ referenced.\n\[PYK\]\ 2014-03-24:\ \ A\ variable\ can\ be\ created\ but\ not\ defined.\ \ `upvar`\ creates\n<<discussion>>\n======\n----\n!!!!!!\n\[\[\n\[Tcl\ syntax\ help\]\ |\n\[Arts\ and\ Crafts\ of\ Tcl-Tk\ Programming\]\n\]\]\n\n%|\ \[Category\ Command\]\ |\ \[Category\ Introspection\]\ |\ \[Category\ Control\ Structure\]\ |%\n!!!!!!} CALL {my revision upvar} CALL {::oo::Obj7408750 process revision/upvar} CALL {::oo::Obj7408748 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