Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/trace?V=47
QUERY_STRINGV=47
CONTENT_TYPE
DOCUMENT_URI/revision/trace
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
REMOTE_ADDR172.69.58.100
REMOTE_PORT24228
SERVER_PORT8888
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip
HTTP_X_FORWARDED_FOR3.147.43.190
HTTP_CF_RAY8867bb7f2e051084-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_IP3.147.43.190
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 trace **\ Summary\ **\n\n'''trace'''\ -\ Monitor\ variable\ accesses,\ command\ usages\ and\ command\ executions\n\n\n\n**\ See\ Also\ **\n\n\ \ \ \[An\ equation\ solver\]:\ \ \ with\ an\ example\ of\ using\ trace\ to\ update\ dependent\ resources\n\n\ \ \ \[Traces\]:\ \ \ examples\ and\ discussion\n\n\ \ \ \[Tracing\ inappropriate\ variable\ access\]:\ \ \ \n\n\ \ \ \[Whole-Script\ Tracing\]:\ \ \ by\ \[DKF\]\n\n\ \ \ \[An\ example\ of\ data\ objects\]:\ \ \ \[AM\]\ Using\ the\ trace\ command,\ I\ implemented\ an\ idea\ by\ George\ Howlett\ (the\ author\ of\ \[BLT\])\n\n\n\n**\ Synopsis\ **\n\n\ \ \ \ :\ \ \ '''trace'''\ ''option''\ ''?arg\ arg\ ...?''\n\n\n\n**\ Documentation\ **\n\n\ \ \ \[http://www.purl.org/tcl/home/man/tcl8.5/TclCmd/trace.htm%|%official\ documentation%|%\]:\ \ \ \n\n\n\n**\ Description\ **\n\nExamples\ of\ what\ to\ do\ with\ \ \[\[`trace`\]:\n\n\ \ \ *\ Communicate\ between\ parts\ of\ a\ \[GUI\]\ and\ the\ internal\ state\ of\ the\ app.\ (Simplified\ \[MVC\],\ observer).\ In\ general\ Communicate\ between\ different\ parts\ of\ an\ app\ without\ coupling\ them\ strongly.\n\n\ \ \ *\ Compute\ simple\ constraints\ for\ a\ number\ of\ variables\ (\"if\ this\ flag\ is\ on\ and\ that\ one\ is\ on,\ then\ no\ other\ is\ allowed\ to\ be\ set\",\ and\ some\ such).\n\n\ \ \ *\ \[bind\]\ \[Canvas\]\ text\ items\ to\ a\ variable,\ effecting\ dynamic\ updates\ \n\n\ \ \ *\ Debug\ -\ call\ a\ proc\ when\ a\ variable\ is\ modified\ (detect\ setting\ from\ wrong\ routine).\n\n\ \ \ *\ Trace\ works\ in\ Itcl\ \[Itcl\ trace\]\ but\ not\ quite\ trivially.\n\n\n\n**\ Examples\ **\n\n***\ order\ of\ processing\ ***\n\n\[JCW\]:\n\n======\nproc\ tellme\ \{id\ a\ e\ op\}\ \{\n\ \ \ \ puts\ \"\ \ \$id\ a=\$a\ e=\$e\ op=\$op\\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ax=\[info\ exists\ ::\$a\]\ ex=\[info\ exists\ ::\$\{a\}(\$e)\]\"\n\}\n\nproc\ do\ \{args\}\ \{\n\ \ \ \ puts\ \"<\$args>\"\n\ \ \ \ uplevel\ \$args\n\}\n\ntrace\ var\ a\ wu\ \{tellme\ array\}\ntrace\ var\ a(1)\ wu\ \{tellme\ element\}\n\nputs\ \[trace\ vinfo\ a\]\nputs\ \[trace\ vinfo\ a(1)\]\n\ndo\ set\ a(0)\ zero\ndo\ set\ a(1)\ one\ndo\ set\ a(2)\ two\ndo\ unset\ a(0)\ndo\ unset\ a(2)\ndo\ unset\ a\n\n#\ output\ is:\n#\n#\ \ \ \{wu\ \{tellme\ array\}\}\n#\ \ \ \{wu\ \{tellme\ element\}\}\n#\ \ \ <set\ a(0)\ zero>\n#\ \ \ \ \ array\ a=a\ e=0\ op=w\ ax=1\ ex=1\n#\ \ \ <set\ a(1)\ one>\n#\ \ \ \ \ array\ a=a\ e=1\ op=w\ ax=1\ ex=1\n#\ \ \ \ \ element\ a=a\ e=1\ op=w\ ax=1\ ex=1\n#\ \ \ <set\ a(2)\ two>\n#\ \ \ \ \ array\ a=a\ e=2\ op=w\ ax=1\ ex=1\n#\ \ \ <unset\ a(0)>\n#\ \ \ \ \ array\ a=a\ e=0\ op=u\ ax=1\ ex=0\n#\ \ \ <unset\ a(2)>\n#\ \ \ \ \ array\ a=a\ e=2\ op=u\ ax=1\ ex=0\n#\ \ \ <unset\ a>\n#\ \ \ \ \ array\ a=a\ e=\ op=u\ ax=0\ ex=0\n#\ \ \ \ \ element\ a=a\ e=1\ op=u\ ax=0\ ex=0\n======\n\n\n\n**\ Variable\ Traces\ **\n\nOn\ \[comp.lang.tcl\],\ 2004-05,\ \[CLN\]\ answers\ \[Erik\ Leunissen\]'s\ question:\ Erik\nLeunissen\ wrote:\n\n======\n>\ The\ following\ passage\ from\ the\ man\ page\ to\ the\ trace\ command\ is\n>\ mystifying\ to\ me:\n>\ \n>\ \"If\ an\ unset\ occurs\ because\ of\ a\ procedure\ return,\ then\ the\ trace\ will\n>\ be\ invoked\ in\ the\ variable\ context\ of\ the\ procedure\ being\ returned\ to:\n>\ the\ stack\ frame\ of\ the\ returning\ procedure\ will\ no\ longer\ exist.\"\n>\ \n>\ I've\ read\ it\ again\ and\ again\;\ I\ can't\ imagine\ how\ a\ procedure\ return\n>\ affects/causes\ an\ unset.\n>\ ...\n\n\n\ \ \ proc\ foo\ \{\ \}\ \{\ \n\ \ \ \ \ \ set\ x\ 1\n\ \ \ \ \ \ trace\ variable\ x\ u\ \{some\ code\ here\}\n\ \ \ \}\n\nWhen\ foo\ is\ invoked,\ x\ is\ created\ (locally),\ has\ a\ trace\ associated\ with\nit,\ then\ becomes\ unset\ as\ foo\ exits.\n======\n\n\n\n**\ Arrays\ **\n\nNon-array\ variables\ give\ a\ null\ string\ for\ the\ ''name2''\ argument\ \ in\ the\ trace\ninvocation,\ but\ the\ null\ string\ is\ a\ perfectly\ valid\ array\ index\ (it\ is\ also\ a\nvalid\ array\ variable\ name),\ so\ a\ null\ value\ for\ ''name2''\ doesn't\ necessarily\nindicate\ that\ the\ traced\ variable\ is\ scalar.\ \ To\ determine\ whether\ a\ variable\nis\ an\ array,\ use:\n\n======\nif\ \{\ \[array\ exists\ \$varname\]\ \}\ \{...\n======\n\n\nAll\ of\ the\ following\ operations\ result\ in\ the\ argument\ values\ `a\ \{\}\ u`:\n\n======\nunset\ a\ \;#\ regular\ var\ a\narray\ unset\ a\nunset\ a()\n======\n\nincluding\ a\ null\ index\ string.\ \ \[\[`\[array\ exists\]`\]\ always\ returns\ false\ for\nthe\ first\ two\ cases,\ and\ true\ for\ the\ third\ (even\ if\ the\ null\ index\ was\ the\nonly\ array\ element).\ There\ is\ no\ way\ for\ the\ trace\ to\ be\ sure\ which\ operation\nwas\ performed.\n\n\[Lars\ H\]:\ Hmm...\ might\ this\ be\ a\ sign\ that\ the\ format\ of\ these\ parameter\ lists\nis\ not\ well\ designed?\ An\ alternative\ would\ have\ been\ to\ put\ the\ operation\ first\nand\ the\ variable\ name\ second,\ so\ that\ there\ needn't\ be\ an\ index\ for\ non-array\naccesses.\ Probably\ too\ late\ to\ change\ now,\ though.\ (Adding\ a\ second\ interface\nwhich\ is\ just\ like\ the\ current\ except\ that\ it\ produces\ parameter\ lists\ in\ a\ new\nformat\ is\ possible,\ but\ probably\ seen\ as\ superfluous.)\n\n\n**\ Arrays\ and\ Upvar\ **\n\nA\ surprising\ (?)\ result\ that\ is\ documented\ in\ the\ \[upvar\]\ manpage:\n\n------\nIf\ \ otherVar\ \ refers\ \ to\ an\ element\ of\ an\ array,\ then\ variable\ traces\nset\ for\ the\ entire\ array\ will\ not\ be\ invoked\ when\ myVar\ is\ accessed\ (but\ntraces\ on\ the\ particular\ element\ will\ still\ be\ invoked).\n------\n\nThis\ means\ that\ using\ a\ trace\ on\ an\ array\ is\ *not*\ sufficient\ to\ capture\ all\nthe\ ways\ elements\ can\ be\ accessed.\ \ For\ instance:\n\n======\npackage\ require\ lambda\nunset\ -nocomplain\ a\ x\ y\narray\ set\ a\ \{x\ 1\ y\ 2\}\ntrace\ add\ variable\ a\ \{array\ read\ write\ unset\}\ \[lambda\ args\ \{puts\ \"::a\ trace:\ \$args\"\}\]\n======\n\nAny\ direct\ use\ of\ `a`\ will\ trigger\ the\ trace:\n\n======\n%\ incr\ a(x)\ \ \ \ \;#\ existing\ element\n::a\ trace:\ a\ x\ read\n::a\ trace:\ a\ x\ write\n\ 2\n%\ incr\ a(z)\ \ \ \ \;#\ new\ element\n::a\ trace:\ a\ z\ read\n::a\ trace:\ a\ z\ write\n\ 1\n%\ unset\ a(x)\n::a\ trace:\ a\ x\ unset\n======\n\nso\ far\ so\ good.\ \ But\ throw\ \[upvar\]\ into\ the\ mix:\n\n======\n%\ upvar\ 0\ a(y)\ y\ \ \ \ \;#\ existing\ element\n%\ upvar\ 0\ a(w)\ w\ \ \ \ \;#\ new\ element\n%\ incr\ y\n\ 3\n%\ incr\ w\n\ 1\n%\ unset\ y\n%\ unset\ w\n=======\n\nNo\ traces\ were\ fired!\ \ If\ you're\ tracing\ an\ array\ whose\ elements\ might\ be\ \[upvar\]ed,\ beware.\n**\ What\ about\ a\ \"variable\ create\"\ Trace?\ **\n\n\[male\]\ 2006-01-24:\ I\ had\ the\ problem,\ that\ I\ wanted\ to\ trace\ the\ creation\ of\ an\narray\ element\ and\ used\ the\ write\ event.\ But\ ...\ the\ write\ event\ is\ fired,\ after\nthe\ new\ array\ element\ was\ already\ created!\ What's\ about\ a\ new\ event\ like\n\"create\"?\ Since\ a\ trace\ may\ be\ created\ on\ non-existent\ variables,\ this\ could\ be\nuseful\ not\ only\ for\ arrays.\n\n----\n\n\[Donald\ Arseneau\]\ Yes,\ write\ traces\ fire\ after\ the\ variable\ has\ already\ been\nset,\ so\ if\ you\ want\ validation\ of\ variables'\ values,\ in\ analogy\ with\ Tk's\n\[entry\ validation\],\ then\ you\ must\ maintain\ shadow\ copies\ of\ the\ previous\nvalues,\ in\ order\ to\ undo\ improper\ settings.\n\n\n\n**\ Triggering\ Traces\ when\ using\ a\ variable\ at\ the\ \[C\]\ level\ **\ \n\nOn\ \[comp.lang.tcl\],\ \[Kevin\ Kenny\]\ answers\ someone\ wanting\ to\ link\ a\ C\ variable\nand\ a\ Tcl\ variable,\ and\ have\ a\ Tcl\ proc\ invoked\ when\ the\ C\ code\ modified\ the\nvariable:\n\n\n\ \ \ \ :\ \ \ Look\ in\ the\ manual\ for\ Tcl_UpdateLinkedVar.\ \ The\ Tcl\ engine\ has\ no\ way\ of\ telling\ that\ you've\ changed\ the\ variable\ in\ C\;\ if\ you\ call\ Tcl_UpdateLinkedVar,\ that\ tells\ it\ your\ value\ has\ changed,\ and\ it\ fires\ the\ traces.\n\n\n\n**\ Simple\ file\ I/O\ in\ traces:\ **\n\n======\ntrace\ var\ stdout\ w\ \{puts\ stdout\ \$stdout\ \;#\}\ntrace\ var\ stdin\ \ r\ \{gets\ stdin\ \ stdin\ \ \ \;#\}\n======\n\nThe\ variables\ are\ named\ like\ the\ file\ handles.\ Little\ demo,\ that\ waits\ for\ninput\ and\ prints\ it\ capitalized:\n\n======\nset\ stdout\ \[string\ toupper\ \$stdin\]\n======\n\n\n\n**\ Managing\ Traces\ **\n\nTraces\ are\ like\ \[widget\]s\ and\ \[image\]s\ in\ that\ they\ are\ resources\ that\ can\ be\nleaked\ and/or\ need\ clean-up.\ \ Counter-intuitive\ results\ sometimes\ arise\ because\ntraces\ are\ additive\ rather\ than\ substitutive\;\ a\ particular\ trace\ can\ fire\ a\nwhole\ chain\ of\ commands.\ \ To\ wipe\ the\ global\ space\ clean\ of\ traces,\n\n======\nforeach\ variable\ \[info\ glob\]\ \{\n\ \ \ \ foreach\ pair\ \[trace\ info\ variable\ ::\$variable\]\ \{\n\ \ \ \ \ \ \ \ foreach\ \{op\ traced_command\}\ \$pair\ \{\}\n\ \ \ \ \ \ \ \ set\ op\ \[string\ range\ \$op\ 0\ 0\]\ \n\ \ \ \ \ \ \ \ trace\ vdelete\ ::\$variable\ \$op\ \$traced_command\n\ \ \ \ \}\n\}\n======\n\n\n\n**\ Traces\ of\ Command\ Executions\ **\n\n***\ step\ traces\ ***\n\n'''enterstep'''\ and\ '''leavestep'''\ traces\ fire\ for\ all\ steps,\n\[recursion%|%recursively%|%\].\ \ When\ this\ is\ undesired,\ the\ depth\ of\ the\nrecursion\ can\ be\ constrained\ by\ having\ the\ trace\ procedure\ look\ at\ \[\[info\nlevel\]\].\ \n\n\ \ \ \ :\ \ \ \[http://groups.google.com/d/msg/comp.lang.tcl/d8KWS-VmxDs/rx0aZp7qOdUJ%|%Interesting\ experience\ with\ execution\ traces\],\ \[comp.lang.tcl\],\ 2003-11-24\n\n\n----\n\n\[Donald\ Arseneau\]\ Another\ tricky\ trap\ is\ that\ errors\ in\ traces\ may\ give\ error\nmessages,\ but\ no\ context\;\ the\ only\ context\ is\ for\ whatever\ triggered\ the\ trace.\nThus,\ if\ you\ ever\ see\ Tk\ error\ messages\ like\ \n\n======\ncan't\ set\ \"xv\":\ invalid\ command\ name\ \"oops\"\n\ \ \ \ while\ executing\n\"incr\ xv\"\n======\n\nthen\ you\ should\ look\ for\ a\ variable\ trace\ on\ the\ xv\ variable.\n\n----\n\n\[Schnexel\]\ Oh\ the\ tricky\ trace\ traps!\ I\ tried\ to\ automaticly\ update\ a\nderivedData\ array\ by\ setting\ a\ trace\ on\ the\ parentData\ array\ (scenario\nsimplified)...\ Now\ I\ get\ a\ surreal\ result:\n\n======\nset\ bla\ \"What\ happened:\\n\"\n\nnamespace\ eval\ bbb\ \{\n\n\ \ \ \ array\ set\ lala\ \[list\ 1\ v1\ 2\ v2\ 3\ v3\]\n\ \ \ \ trace\ add\ variable\ ::bbb::lala\ \{read\ array\}\ ::bbb::tra\n\ \ \ \ proc\ tra\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ append\ ::bla\ \"\\n\ (TRACE\ \$args)\"\n\ \ \ \ \ \ \ \ array\ unset\ ::bbb::lala\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ also\ deletes\ trace\ (yet\ the\ \"array\"\ op\ still\ fires)\n\ \ \ \ \ \ \ \ foreach\ \{n\ v\}\ \ \[list\ 1\ trv1\ 2\ trv2\ 3\ trv3\]\ \{\ set\ ::bbb::lala(\$n)\ \$v\ \}\n\ \ \ \ \}\n\}\n\nnamespace\ eval\ aaa\ \{\n\ \ \ \ append\ ::bla\ \"\\n\\\[info\ exists\ ::bbb::lala(1)\\\]==...\"\;\ append\ ::bla\ ...\ \[info\ exists\ ::bbb::lala(1)\]\n\ \ \ \ append\ ::bla\ \"\\n\\\[info\ exists\ ::bbb::lala(1)\\\]==...\"\;\ append\ ::bla\ ...\ \[info\ exists\ ::bbb::lala(1)\]\n\ \ \ \ append\ ::bla\ \"\\n\\\$::bbb::lala(1)==...\"\;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ append\ ::bla\ ...\ \$::bbb::lala(1)\n\}\n\nputs\ \$bla\n======\n\nwhich\ gives\ the\ output\n\n======none\nWhat\ happened:\n\[info\ exists\ ::bbb::lala(1)\]==...\n\ (TRACE\ ::bbb::lala\ 1\ read)\n\ (TRACE\ ::bbb::lala\ \{\}\ array)...0\n\[info\ exists\ ::bbb::lala(1)\]==......1\n\$::bbb::lala(1)==......trv1\n======\n\nSo,\ upon\ first\ read\ access\ of\ lala,\ it\ does\ not\ exist\ anymore,\ whilst\ upon\nsecond\ read\ it\ is\ there.\ Can\ anybody\ make\ sense\ of\ this?\n\n\[Lars\ H\]:\ Regarding\ why\ the\ \"array\"\ op\ fires:\ It\ it\ fires\ at\ the\ very\ \[\[array\nunset\ ::bbb::lala\]\]\ where\ you\ comment\ upon\ this,\ i.e.,\ before\ the\ \[foreach\],\nwhich\ is\ consistent\ with\ the\ \[trace\]\ manpage\ (only\ read\ and\ write\ traces\ are\ndisabled\ inside\ a\ read\ or\ write\ trace).\ But\ why\ \[info\ exists\]\ reports\ 0\ I\ don't\nknow...\ Perhaps\ some\ caching\ issue\ (the\ variable\ that\ was\ looked\ up\ is\ not\ the\none\ that\ is\ there\ when\ the\ result\ is\ returned)?\ You'll\ probably\ need\ to\ read\nthe\ source\ to\ find\ out.\n\n\[Schnexel\]:\ Wrrr...\ Here´s\ a\ simpler\ example.\ Array\ trace\ is\ bugged!\n\n======\narray\ set\ ::lala\ \[list\ 1\ v1\ \ 2\ v2\]\narray\ set\ ::lala\ \[list\ 3\ v3\ \ 4\ v4\]\nputs\ \"\\\$::lala==\[array\ get\ ::lala\]\"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ O.K.\n\ntrace\ add\ variable\ ::lala\ read\ ::tra\n\n\nproc\ tra\ \{\ args\ \}\ \{\n\ \ \ \ puts\ \"\ \ \ \ (TRACE\ \$args)\"\n\ \ \ \ trace\ remove\ variable\ ::lala\ read\ ::tra\n\n\ \ \ \ array\ set\ ::lala\ \ \ \[list\ A\ trvA\ \ B\ trvB\]\n\ \ \ \ puts\ \"\ \ \ \ within\ trace:\ \ \\\$::lala==\[array\ get\ ::lala\]\"\ \;#\ O.K.\n\}\n\nputs\ \"1st\ read\ outside:\ \ \\\$::lala==\[array\ get\ ::lala\]\"\ \ \ \ \ \ \;#\ not\ O.K.\ !\nputs\ \"2nd\ read\ outside:\ \ \\\$::lala==\[array\ get\ ::lala\]\"\ \ \ \ \ \ \;#\ O.K.\n======\n\nOutput:\n\n======none\n\$::lala==4\ v4\ 1\ v1\ 2\ v2\ 3\ v3\nreading\ ::lala\n\ \ \ \ (TRACE\ ::lala\ 4\ read)\n\ \ \ \ within\ trace:\ \ \$::lala==4\ v4\ A\ trvA\ 1\ v1\ B\ trvB\ 2\ v2\ 3\ v3\n1st\ read\ outside:\ \ \$::lala==4\ v4\ 1\ v1\ 2\ v2\ 3\ v3\n2nd\ read\ outside:\ \ \$::lala==4\ v4\ A\ trvA\ 1\ v1\ B\ trvB\ 2\ v2\ 3\ v3\n======\n\n\n\n**\ Proposal:\ \ Modify\ `trace\ command\ ...\ enter`\ to\ Act\ as\ a\ Command\ Filter\ **\n\n\[PYK\]\ 2013-12-22:\ The\ result\ of\ a\ command\ run\ as\ a\ trace\ are\ currently\ndiscarded.\ \ It\ could\ instead\ be\ used\ as\ the\ command\ to\ actually\ call.\nFor\ exampe,\ the\ result\ of\ the\ following\ script\ would\ be\ `12`,\ not\ `21`\n\n======\nproc\ add\ \{args\}\ \{\n\ \ \ \ ::tcl::mathop::+\ \{*\}\$args\n\}\n\ntrace\ add\ execution\ add\ enter\ \{apply\ \{\{cmd\ op\}\ \{\n\ \ \ \ set\ args\ \[lassign\ \$cmd\ name\]\n\ \ \ \ foreach\ arg\ \$args\[set\ args\ \{\}\]\ \{\n\ \ \ \ \ \ \ \ if\ \{\$arg\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ args\ \$arg\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ return\ \[linsert\ \$args\ 0\ \$name\]\ \n\}\}\}\n\nadd\ 1\ 2\ 3\ 4\ 5\ 6\n======\n\n\n\n\n<<categories>>\ Tcl\ syntax\ |\ Arts\ and\ crafts\ of\ Tcl-Tk\ programming\ |\ Command regexp2} CALL {my render trace **\ Summary\ **\n\n'''trace'''\ -\ Monitor\ variable\ accesses,\ command\ usages\ and\ command\ executions\n\n\n\n**\ See\ Also\ **\n\n\ \ \ \[An\ equation\ solver\]:\ \ \ with\ an\ example\ of\ using\ trace\ to\ update\ dependent\ resources\n\n\ \ \ \[Traces\]:\ \ \ examples\ and\ discussion\n\n\ \ \ \[Tracing\ inappropriate\ variable\ access\]:\ \ \ \n\n\ \ \ \[Whole-Script\ Tracing\]:\ \ \ by\ \[DKF\]\n\n\ \ \ \[An\ example\ of\ data\ objects\]:\ \ \ \[AM\]\ Using\ the\ trace\ command,\ I\ implemented\ an\ idea\ by\ George\ Howlett\ (the\ author\ of\ \[BLT\])\n\n\n\n**\ Synopsis\ **\n\n\ \ \ \ :\ \ \ '''trace'''\ ''option''\ ''?arg\ arg\ ...?''\n\n\n\n**\ Documentation\ **\n\n\ \ \ \[http://www.purl.org/tcl/home/man/tcl8.5/TclCmd/trace.htm%|%official\ documentation%|%\]:\ \ \ \n\n\n\n**\ Description\ **\n\nExamples\ of\ what\ to\ do\ with\ \ \[\[`trace`\]:\n\n\ \ \ *\ Communicate\ between\ parts\ of\ a\ \[GUI\]\ and\ the\ internal\ state\ of\ the\ app.\ (Simplified\ \[MVC\],\ observer).\ In\ general\ Communicate\ between\ different\ parts\ of\ an\ app\ without\ coupling\ them\ strongly.\n\n\ \ \ *\ Compute\ simple\ constraints\ for\ a\ number\ of\ variables\ (\"if\ this\ flag\ is\ on\ and\ that\ one\ is\ on,\ then\ no\ other\ is\ allowed\ to\ be\ set\",\ and\ some\ such).\n\n\ \ \ *\ \[bind\]\ \[Canvas\]\ text\ items\ to\ a\ variable,\ effecting\ dynamic\ updates\ \n\n\ \ \ *\ Debug\ -\ call\ a\ proc\ when\ a\ variable\ is\ modified\ (detect\ setting\ from\ wrong\ routine).\n\n\ \ \ *\ Trace\ works\ in\ Itcl\ \[Itcl\ trace\]\ but\ not\ quite\ trivially.\n\n\n\n**\ Examples\ **\n\n***\ order\ of\ processing\ ***\n\n\[JCW\]:\n\n======\nproc\ tellme\ \{id\ a\ e\ op\}\ \{\n\ \ \ \ puts\ \"\ \ \$id\ a=\$a\ e=\$e\ op=\$op\\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ax=\[info\ exists\ ::\$a\]\ ex=\[info\ exists\ ::\$\{a\}(\$e)\]\"\n\}\n\nproc\ do\ \{args\}\ \{\n\ \ \ \ puts\ \"<\$args>\"\n\ \ \ \ uplevel\ \$args\n\}\n\ntrace\ var\ a\ wu\ \{tellme\ array\}\ntrace\ var\ a(1)\ wu\ \{tellme\ element\}\n\nputs\ \[trace\ vinfo\ a\]\nputs\ \[trace\ vinfo\ a(1)\]\n\ndo\ set\ a(0)\ zero\ndo\ set\ a(1)\ one\ndo\ set\ a(2)\ two\ndo\ unset\ a(0)\ndo\ unset\ a(2)\ndo\ unset\ a\n\n#\ output\ is:\n#\n#\ \ \ \{wu\ \{tellme\ array\}\}\n#\ \ \ \{wu\ \{tellme\ element\}\}\n#\ \ \ <set\ a(0)\ zero>\n#\ \ \ \ \ array\ a=a\ e=0\ op=w\ ax=1\ ex=1\n#\ \ \ <set\ a(1)\ one>\n#\ \ \ \ \ array\ a=a\ e=1\ op=w\ ax=1\ ex=1\n#\ \ \ \ \ element\ a=a\ e=1\ op=w\ ax=1\ ex=1\n#\ \ \ <set\ a(2)\ two>\n#\ \ \ \ \ array\ a=a\ e=2\ op=w\ ax=1\ ex=1\n#\ \ \ <unset\ a(0)>\n#\ \ \ \ \ array\ a=a\ e=0\ op=u\ ax=1\ ex=0\n#\ \ \ <unset\ a(2)>\n#\ \ \ \ \ array\ a=a\ e=2\ op=u\ ax=1\ ex=0\n#\ \ \ <unset\ a>\n#\ \ \ \ \ array\ a=a\ e=\ op=u\ ax=0\ ex=0\n#\ \ \ \ \ element\ a=a\ e=1\ op=u\ ax=0\ ex=0\n======\n\n\n\n**\ Variable\ Traces\ **\n\nOn\ \[comp.lang.tcl\],\ 2004-05,\ \[CLN\]\ answers\ \[Erik\ Leunissen\]'s\ question:\ Erik\nLeunissen\ wrote:\n\n======\n>\ The\ following\ passage\ from\ the\ man\ page\ to\ the\ trace\ command\ is\n>\ mystifying\ to\ me:\n>\ \n>\ \"If\ an\ unset\ occurs\ because\ of\ a\ procedure\ return,\ then\ the\ trace\ will\n>\ be\ invoked\ in\ the\ variable\ context\ of\ the\ procedure\ being\ returned\ to:\n>\ the\ stack\ frame\ of\ the\ returning\ procedure\ will\ no\ longer\ exist.\"\n>\ \n>\ I've\ read\ it\ again\ and\ again\;\ I\ can't\ imagine\ how\ a\ procedure\ return\n>\ affects/causes\ an\ unset.\n>\ ...\n\n\n\ \ \ proc\ foo\ \{\ \}\ \{\ \n\ \ \ \ \ \ set\ x\ 1\n\ \ \ \ \ \ trace\ variable\ x\ u\ \{some\ code\ here\}\n\ \ \ \}\n\nWhen\ foo\ is\ invoked,\ x\ is\ created\ (locally),\ has\ a\ trace\ associated\ with\nit,\ then\ becomes\ unset\ as\ foo\ exits.\n======\n\n\n\n**\ Arrays\ **\n\nNon-array\ variables\ give\ a\ null\ string\ for\ the\ ''name2''\ argument\ \ in\ the\ trace\ninvocation,\ but\ the\ null\ string\ is\ a\ perfectly\ valid\ array\ index\ (it\ is\ also\ a\nvalid\ array\ variable\ name),\ so\ a\ null\ value\ for\ ''name2''\ doesn't\ necessarily\nindicate\ that\ the\ traced\ variable\ is\ scalar.\ \ To\ determine\ whether\ a\ variable\nis\ an\ array,\ use:\n\n======\nif\ \{\ \[array\ exists\ \$varname\]\ \}\ \{...\n======\n\n\nAll\ of\ the\ following\ operations\ result\ in\ the\ argument\ values\ `a\ \{\}\ u`:\n\n======\nunset\ a\ \;#\ regular\ var\ a\narray\ unset\ a\nunset\ a()\n======\n\nincluding\ a\ null\ index\ string.\ \ \[\[`\[array\ exists\]`\]\ always\ returns\ false\ for\nthe\ first\ two\ cases,\ and\ true\ for\ the\ third\ (even\ if\ the\ null\ index\ was\ the\nonly\ array\ element).\ There\ is\ no\ way\ for\ the\ trace\ to\ be\ sure\ which\ operation\nwas\ performed.\n\n\[Lars\ H\]:\ Hmm...\ might\ this\ be\ a\ sign\ that\ the\ format\ of\ these\ parameter\ lists\nis\ not\ well\ designed?\ An\ alternative\ would\ have\ been\ to\ put\ the\ operation\ first\nand\ the\ variable\ name\ second,\ so\ that\ there\ needn't\ be\ an\ index\ for\ non-array\naccesses.\ Probably\ too\ late\ to\ change\ now,\ though.\ (Adding\ a\ second\ interface\nwhich\ is\ just\ like\ the\ current\ except\ that\ it\ produces\ parameter\ lists\ in\ a\ new\nformat\ is\ possible,\ but\ probably\ seen\ as\ superfluous.)\n\n\n**\ Arrays\ and\ Upvar\ **\n\nA\ surprising\ (?)\ result\ that\ is\ documented\ in\ the\ \[upvar\]\ manpage:\n\n------\nIf\ \ otherVar\ \ refers\ \ to\ an\ element\ of\ an\ array,\ then\ variable\ traces\nset\ for\ the\ entire\ array\ will\ not\ be\ invoked\ when\ myVar\ is\ accessed\ (but\ntraces\ on\ the\ particular\ element\ will\ still\ be\ invoked).\n------\n\nThis\ means\ that\ using\ a\ trace\ on\ an\ array\ is\ *not*\ sufficient\ to\ capture\ all\nthe\ ways\ elements\ can\ be\ accessed.\ \ For\ instance:\n\n======\npackage\ require\ lambda\nunset\ -nocomplain\ a\ x\ y\narray\ set\ a\ \{x\ 1\ y\ 2\}\ntrace\ add\ variable\ a\ \{array\ read\ write\ unset\}\ \[lambda\ args\ \{puts\ \"::a\ trace:\ \$args\"\}\]\n======\n\nAny\ direct\ use\ of\ `a`\ will\ trigger\ the\ trace:\n\n======\n%\ incr\ a(x)\ \ \ \ \;#\ existing\ element\n::a\ trace:\ a\ x\ read\n::a\ trace:\ a\ x\ write\n\ 2\n%\ incr\ a(z)\ \ \ \ \;#\ new\ element\n::a\ trace:\ a\ z\ read\n::a\ trace:\ a\ z\ write\n\ 1\n%\ unset\ a(x)\n::a\ trace:\ a\ x\ unset\n======\n\nso\ far\ so\ good.\ \ But\ throw\ \[upvar\]\ into\ the\ mix:\n\n======\n%\ upvar\ 0\ a(y)\ y\ \ \ \ \;#\ existing\ element\n%\ upvar\ 0\ a(w)\ w\ \ \ \ \;#\ new\ element\n%\ incr\ y\n\ 3\n%\ incr\ w\n\ 1\n%\ unset\ y\n%\ unset\ w\n=======\n\nNo\ traces\ were\ fired!\ \ If\ you're\ tracing\ an\ array\ whose\ elements\ might\ be\ \[upvar\]ed,\ beware.\n**\ What\ about\ a\ \"variable\ create\"\ Trace?\ **\n\n\[male\]\ 2006-01-24:\ I\ had\ the\ problem,\ that\ I\ wanted\ to\ trace\ the\ creation\ of\ an\narray\ element\ and\ used\ the\ write\ event.\ But\ ...\ the\ write\ event\ is\ fired,\ after\nthe\ new\ array\ element\ was\ already\ created!\ What's\ about\ a\ new\ event\ like\n\"create\"?\ Since\ a\ trace\ may\ be\ created\ on\ non-existent\ variables,\ this\ could\ be\nuseful\ not\ only\ for\ arrays.\n\n----\n\n\[Donald\ Arseneau\]\ Yes,\ write\ traces\ fire\ after\ the\ variable\ has\ already\ been\nset,\ so\ if\ you\ want\ validation\ of\ variables'\ values,\ in\ analogy\ with\ Tk's\n\[entry\ validation\],\ then\ you\ must\ maintain\ shadow\ copies\ of\ the\ previous\nvalues,\ in\ order\ to\ undo\ improper\ settings.\n\n\n\n**\ Triggering\ Traces\ when\ using\ a\ variable\ at\ the\ \[C\]\ level\ **\ \n\nOn\ \[comp.lang.tcl\],\ \[Kevin\ Kenny\]\ answers\ someone\ wanting\ to\ link\ a\ C\ variable\nand\ a\ Tcl\ variable,\ and\ have\ a\ Tcl\ proc\ invoked\ when\ the\ C\ code\ modified\ the\nvariable:\n\n\n\ \ \ \ :\ \ \ Look\ in\ the\ manual\ for\ Tcl_UpdateLinkedVar.\ \ The\ Tcl\ engine\ has\ no\ way\ of\ telling\ that\ you've\ changed\ the\ variable\ in\ C\;\ if\ you\ call\ Tcl_UpdateLinkedVar,\ that\ tells\ it\ your\ value\ has\ changed,\ and\ it\ fires\ the\ traces.\n\n\n\n**\ Simple\ file\ I/O\ in\ traces:\ **\n\n======\ntrace\ var\ stdout\ w\ \{puts\ stdout\ \$stdout\ \;#\}\ntrace\ var\ stdin\ \ r\ \{gets\ stdin\ \ stdin\ \ \ \;#\}\n======\n\nThe\ variables\ are\ named\ like\ the\ file\ handles.\ Little\ demo,\ that\ waits\ for\ninput\ and\ prints\ it\ capitalized:\n\n======\nset\ stdout\ \[string\ toupper\ \$stdin\]\n======\n\n\n\n**\ Managing\ Traces\ **\n\nTraces\ are\ like\ \[widget\]s\ and\ \[image\]s\ in\ that\ they\ are\ resources\ that\ can\ be\nleaked\ and/or\ need\ clean-up.\ \ Counter-intuitive\ results\ sometimes\ arise\ because\ntraces\ are\ additive\ rather\ than\ substitutive\;\ a\ particular\ trace\ can\ fire\ a\nwhole\ chain\ of\ commands.\ \ To\ wipe\ the\ global\ space\ clean\ of\ traces,\n\n======\nforeach\ variable\ \[info\ glob\]\ \{\n\ \ \ \ foreach\ pair\ \[trace\ info\ variable\ ::\$variable\]\ \{\n\ \ \ \ \ \ \ \ foreach\ \{op\ traced_command\}\ \$pair\ \{\}\n\ \ \ \ \ \ \ \ set\ op\ \[string\ range\ \$op\ 0\ 0\]\ \n\ \ \ \ \ \ \ \ trace\ vdelete\ ::\$variable\ \$op\ \$traced_command\n\ \ \ \ \}\n\}\n======\n\n\n\n**\ Traces\ of\ Command\ Executions\ **\n\n***\ step\ traces\ ***\n\n'''enterstep'''\ and\ '''leavestep'''\ traces\ fire\ for\ all\ steps,\n\[recursion%|%recursively%|%\].\ \ When\ this\ is\ undesired,\ the\ depth\ of\ the\nrecursion\ can\ be\ constrained\ by\ having\ the\ trace\ procedure\ look\ at\ \[\[info\nlevel\]\].\ \n\n\ \ \ \ :\ \ \ \[http://groups.google.com/d/msg/comp.lang.tcl/d8KWS-VmxDs/rx0aZp7qOdUJ%|%Interesting\ experience\ with\ execution\ traces\],\ \[comp.lang.tcl\],\ 2003-11-24\n\n\n----\n\n\[Donald\ Arseneau\]\ Another\ tricky\ trap\ is\ that\ errors\ in\ traces\ may\ give\ error\nmessages,\ but\ no\ context\;\ the\ only\ context\ is\ for\ whatever\ triggered\ the\ trace.\nThus,\ if\ you\ ever\ see\ Tk\ error\ messages\ like\ \n\n======\ncan't\ set\ \"xv\":\ invalid\ command\ name\ \"oops\"\n\ \ \ \ while\ executing\n\"incr\ xv\"\n======\n\nthen\ you\ should\ look\ for\ a\ variable\ trace\ on\ the\ xv\ variable.\n\n----\n\n\[Schnexel\]\ Oh\ the\ tricky\ trace\ traps!\ I\ tried\ to\ automaticly\ update\ a\nderivedData\ array\ by\ setting\ a\ trace\ on\ the\ parentData\ array\ (scenario\nsimplified)...\ Now\ I\ get\ a\ surreal\ result:\n\n======\nset\ bla\ \"What\ happened:\\n\"\n\nnamespace\ eval\ bbb\ \{\n\n\ \ \ \ array\ set\ lala\ \[list\ 1\ v1\ 2\ v2\ 3\ v3\]\n\ \ \ \ trace\ add\ variable\ ::bbb::lala\ \{read\ array\}\ ::bbb::tra\n\ \ \ \ proc\ tra\ \{\ args\ \}\ \{\n\ \ \ \ \ \ \ \ append\ ::bla\ \"\\n\ (TRACE\ \$args)\"\n\ \ \ \ \ \ \ \ array\ unset\ ::bbb::lala\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ also\ deletes\ trace\ (yet\ the\ \"array\"\ op\ still\ fires)\n\ \ \ \ \ \ \ \ foreach\ \{n\ v\}\ \ \[list\ 1\ trv1\ 2\ trv2\ 3\ trv3\]\ \{\ set\ ::bbb::lala(\$n)\ \$v\ \}\n\ \ \ \ \}\n\}\n\nnamespace\ eval\ aaa\ \{\n\ \ \ \ append\ ::bla\ \"\\n\\\[info\ exists\ ::bbb::lala(1)\\\]==...\"\;\ append\ ::bla\ ...\ \[info\ exists\ ::bbb::lala(1)\]\n\ \ \ \ append\ ::bla\ \"\\n\\\[info\ exists\ ::bbb::lala(1)\\\]==...\"\;\ append\ ::bla\ ...\ \[info\ exists\ ::bbb::lala(1)\]\n\ \ \ \ append\ ::bla\ \"\\n\\\$::bbb::lala(1)==...\"\;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ append\ ::bla\ ...\ \$::bbb::lala(1)\n\}\n\nputs\ \$bla\n======\n\nwhich\ gives\ the\ output\n\n======none\nWhat\ happened:\n\[info\ exists\ ::bbb::lala(1)\]==...\n\ (TRACE\ ::bbb::lala\ 1\ read)\n\ (TRACE\ ::bbb::lala\ \{\}\ array)...0\n\[info\ exists\ ::bbb::lala(1)\]==......1\n\$::bbb::lala(1)==......trv1\n======\n\nSo,\ upon\ first\ read\ access\ of\ lala,\ it\ does\ not\ exist\ anymore,\ whilst\ upon\nsecond\ read\ it\ is\ there.\ Can\ anybody\ make\ sense\ of\ this?\n\n\[Lars\ H\]:\ Regarding\ why\ the\ \"array\"\ op\ fires:\ It\ it\ fires\ at\ the\ very\ \[\[array\nunset\ ::bbb::lala\]\]\ where\ you\ comment\ upon\ this,\ i.e.,\ before\ the\ \[foreach\],\nwhich\ is\ consistent\ with\ the\ \[trace\]\ manpage\ (only\ read\ and\ write\ traces\ are\ndisabled\ inside\ a\ read\ or\ write\ trace).\ But\ why\ \[info\ exists\]\ reports\ 0\ I\ don't\nknow...\ Perhaps\ some\ caching\ issue\ (the\ variable\ that\ was\ looked\ up\ is\ not\ the\none\ that\ is\ there\ when\ the\ result\ is\ returned)?\ You'll\ probably\ need\ to\ read\nthe\ source\ to\ find\ out.\n\n\[Schnexel\]:\ Wrrr...\ Here´s\ a\ simpler\ example.\ Array\ trace\ is\ bugged!\n\n======\narray\ set\ ::lala\ \[list\ 1\ v1\ \ 2\ v2\]\narray\ set\ ::lala\ \[list\ 3\ v3\ \ 4\ v4\]\nputs\ \"\\\$::lala==\[array\ get\ ::lala\]\"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ O.K.\n\ntrace\ add\ variable\ ::lala\ read\ ::tra\n\n\nproc\ tra\ \{\ args\ \}\ \{\n\ \ \ \ puts\ \"\ \ \ \ (TRACE\ \$args)\"\n\ \ \ \ trace\ remove\ variable\ ::lala\ read\ ::tra\n\n\ \ \ \ array\ set\ ::lala\ \ \ \[list\ A\ trvA\ \ B\ trvB\]\n\ \ \ \ puts\ \"\ \ \ \ within\ trace:\ \ \\\$::lala==\[array\ get\ ::lala\]\"\ \;#\ O.K.\n\}\n\nputs\ \"1st\ read\ outside:\ \ \\\$::lala==\[array\ get\ ::lala\]\"\ \ \ \ \ \ \;#\ not\ O.K.\ !\nputs\ \"2nd\ read\ outside:\ \ \\\$::lala==\[array\ get\ ::lala\]\"\ \ \ \ \ \ \;#\ O.K.\n======\n\nOutput:\n\n======none\n\$::lala==4\ v4\ 1\ v1\ 2\ v2\ 3\ v3\nreading\ ::lala\n\ \ \ \ (TRACE\ ::lala\ 4\ read)\n\ \ \ \ within\ trace:\ \ \$::lala==4\ v4\ A\ trvA\ 1\ v1\ B\ trvB\ 2\ v2\ 3\ v3\n1st\ read\ outside:\ \ \$::lala==4\ v4\ 1\ v1\ 2\ v2\ 3\ v3\n2nd\ read\ outside:\ \ \$::lala==4\ v4\ A\ trvA\ 1\ v1\ B\ trvB\ 2\ v2\ 3\ v3\n======\n\n\n\n**\ Proposal:\ \ Modify\ `trace\ command\ ...\ enter`\ to\ Act\ as\ a\ Command\ Filter\ **\n\n\[PYK\]\ 2013-12-22:\ The\ result\ of\ a\ command\ run\ as\ a\ trace\ are\ currently\ndiscarded.\ \ It\ could\ instead\ be\ used\ as\ the\ command\ to\ actually\ call.\nFor\ exampe,\ the\ result\ of\ the\ following\ script\ would\ be\ `12`,\ not\ `21`\n\n======\nproc\ add\ \{args\}\ \{\n\ \ \ \ ::tcl::mathop::+\ \{*\}\$args\n\}\n\ntrace\ add\ execution\ add\ enter\ \{apply\ \{\{cmd\ op\}\ \{\n\ \ \ \ set\ args\ \[lassign\ \$cmd\ name\]\n\ \ \ \ foreach\ arg\ \$args\[set\ args\ \{\}\]\ \{\n\ \ \ \ \ \ \ \ if\ \{\$arg\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ args\ \$arg\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \}\n\ \ \ \ return\ \[linsert\ \$args\ 0\ \$name\]\ \n\}\}\}\n\nadd\ 1\ 2\ 3\ 4\ 5\ 6\n======\n\n\n\n\n<<categories>>\ Tcl\ syntax\ |\ Arts\ and\ crafts\ of\ Tcl-Tk\ programming\ |\ Command} CALL {my revision trace} CALL {::oo::Obj2347145 process revision/trace} CALL {::oo::Obj2347143 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