Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/switch?V=85
QUERY_STRINGV=85
CONTENT_TYPE
DOCUMENT_URI/revision/switch
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.178.153
REMOTE_PORT47178
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR18.222.115.120
HTTP_CF_RAY8773880f683d02c8-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_IP18.222.115.120
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 switch Documentation\ for\ the\ Tcl\ switch\ command\ can\ be\ found\ at\nhttp://www.purl.org/tcl/home/man/tcl8.5/TclCmd/switch.htm\ \n\nHistory\ corner:\ First\ announced\ by\ \[JO\]\ for\ Tcl\ 7.0\ in\ \[http://groups.google.com/groups?q=group:comp.lang.tcl+author:ousterhout&start=800&hl=de&lr=&newwindow=1&scoring=d&selm=1t8s4g%24kfs%40agate.berkeley.edu&rnum=840\]\n\nThere\ is\ a\ typo\ in\ the\ current\ switch.html\ documenation.\ \ It\ should\ read:\n======\n\ \ \ \ switch\ abc\ \"a\ -\ b\"\ \{expr\ \{1\}\}\ \$foo\ \{expr\ \{2\}\}\ default\ \{expr\ \{3\}\}\n======\n'''switch'''\ supersedes\ \[\[\[case\]\]\].\n**\ Synopsis\ **\n<<discussion>>\n\[RS\]\ Make\ sure\ you\ always\ write\ \"the\ switch\ to\ end\ all\ switches\",\ \"--\",\ if\ there\ is\ \nthe\ slightest\ possibility\ that\ faulty\ or\ unexpected\ data\ (i.e.,\ beginning\ with\ a\ dash)\ \nmay\ occur\ -\ they\ raise\ a\ data-driven\ syntax\ error\ which\ does\ not\ make\ a\ good\ impression\ on\ end-users.\n\ switch\ --\ \$foo\ \{...\}\ \ \;#\ robust\ for\ all\ values\ of\ foo\nIn\ Tcl\ versions\ prior\ to\ \[Changes\ in\ Tcl/Tk\ 8.5%|%8.5\],\ \ `--`\ should\ be\ used\n\[AMG\]:\ Actually,\ \"--\"\ is\ not\ required\ when\ using\ this\ form\ of\ \[\[switch\]\]\ \[http://www.tcl.tk/man/tcl8.6/TclCmd/switch.htm#M11\].\ \ It's\ only\ needed\ when\ the\ patterns\ and\ bodies\ are\ separate\ arguments,\ which\ is\ a\ relatively\ rare\ usage\ of\ \[\[switch\]\].\nWith\ exactly\ one\ argument,\ that\ argument\ is\ a\ \[dict%|%dictionary\]\ of\ patterns\n\[AMG\],\ update:\ On\ second\ thought,\ \"--\"\ is\ required,\ if\ you're\ using\ Tcl\ 8.4\ or\ older.\ \ Tcl\ 8.5+\ doesn't\ require\ it.\n\n----\nIn\ the\ form\ of\ the\ switch\ command\ where\ all\ patterns\ and\ bodies\ are\ in\ the\ last\ argument,\ this\ argument\ is\ technically\ a\ string\ which\ will\ be\ parsed\ by\ Tcl\ as\ a\ list.\ The\ rules\ for\ how\ a\ string\ is\ parsed\ as\ a\ list\ can\ be\ found\ on\ the\ \[lindex\]\ manual\ page\ \[http://www.purl.org/tcl/home/man/tcl8.5/TclCmd/lindex.htm\].\nThe\ difference\ here\ between\ a\ whitespace-delimited\ substring\ and\ a\ list\ element\ parsed\ from\ a\ string\ is\ usually\ negligible,\ but\ one\ must\ sometimes\ take\ them\ into\ account\ to\ get\ the\ right\ amount\ of\ quoting\ in\ place.\ \nRegexp\ patterns\ are\ particularly\ easy\ to\ overquote.\n`switch`\ only\ performs\ string\ comparison,\ so\ it\ isn't\ ideal\ for\ numeric\n----\nCoding\ style\ for\ switch\ is\ tricky.\ \ Recently\ on\ comp.lang.tcl\ there\ was\nan\ exchange\ about\ getting\ switch\ to\ work\ right.\ \ The\ user\ had\ originally\n\nswitch\ \$::errorCode\ \{\n\ \ \ \ \$NOTFOUND\ \{\n\ \ \ \ \ \ \ \ puts\ \{page\ not\ found\}\n\ \ \ \ \ \ \ \ puts\ \"page\ not\ found\ \"\n\ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ puts\ \"Program\ encountered\ code\ \$::errorCode\"\n\ \ \ \ \ \ \ \ break\n\ \ \ \ \}\n\}\n======\n\n\n\[PYK\]\ 2014-05-29:\ \[scripted\ list\]\ can\ make\ this\ syntax\ work,\ and\ even\ allows\ comments:\n----\n\[PZ\]\ 'default'\ alternative\ for\ regexp:\n======\nset\ a\ x\nswitch\ -regexp\ --\ \$a\ \{\n\ \ \ \ \ \ \ \ \ y\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"y\"\n\ \ \ \ \ \ \ \ \ \}\n\ \n\ \ \ \ \ \ \ \ \ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"z\"\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"\$a\"\n\ \ \ \ \ \ \ \ \ \}\n\}\n======\nreturns:\n======\n\ z\n\n----\n\[LV\]\ When\ I\ try\ to\ use\ a\ break\ inside\ of\ a\ switch\ command,\ I\ get\ the\ error\n\nswitch\ \$::errorCode\ \[sl\ \{\ninvoked\ \"break\"\ outside\ of\ a\ loop\n\ \ \ \ while\ executing\n\"switch\ \n\nA\ well-known\ Tcl\ pundit\ suggested:\nIs\ there\ an\ equivalent\ to\ \[break\]\ for\ switch?\n======\n\[YSK\]\ How\ about\ trapping\ \"switch\"\ in\ \"while\ 1\":\n\nswitch\ \$::errorCode\ \"\nwhile\ \{1\}\ \{\nswitch\ \$cond\ \{\ncase1\ \{\n\ \ \ if\ \{\$fault\}\ \{puts\ NG\;\ break\}\n\ \ \ puts\ OK\ \ \ \ \n\}\ndefault\ \{\n\ \ \ puts\ OK\n\}\nbreak\n\}\n======\n\n\[MG\]\ Hrm,\ I\ thought\ \[break\]\ worked\ in\ switches,\ too.\ But\ it\ seems\ that\ Tcl's\ \[switch\]\ doesn't\ fall\ through\ by\ default:\n\n======\nswitch\ -glob\ --\ foo\ \\\n\ \ f*\ \{puts\ match1\}\ \\\n\ \ *o*\ \{puts\ match2\}\ \\\n\ \ default\ \{puts\ nomatch\}\n======\n\nOnly\ the\ \"match1\"\ is\ shown,\ and\ then\ it\ stops,\ there's\ no\ \"match2\".\ So\ no\ \[break\]\ is\ needed,\ it'll\ stop\ when\ a\ match\ is\ found\ anyway.\ That\ means,\ in\ something\ like\n\n======\nswitch\ -glob\ --\ \$string\ \\\n\ \ f*\ \{puts\ foo\}\n\ \ b*\ \{puts\ bar\}\n\ \ *z*\ \{#\ do\ nothing\}\n\ \ default\ \{puts\ \"something\ else\"\}\n======\n\nthe\ \"#\ do\ nothing\"\ case\ has\ the\ same\ effect\ as\ a\ \[break\]\ in\ a\ switch\ in\ \[C\]\ would.\n\n\[LV\]\ without\ break,\ it\ means\ that\ one\ has\ to\ code\ carefully\ to\ avoid\ the\ cases\ where\ one\ normally\ would\ use\ it.\ For\ instance,\ in\ other\ languages,\ one\ might\ code\n\n======\nswitch\ \$variable\ \{\ncase1\ \{do\ this\;\ break\}\ncase2\ \{do\ that\;\ break\}\ncase3\ \{if\ today\ is\ Monday,\ do\ the\ other\;\ break\;\ if\ tomorrow\ is\ the\ 14th,\ do\ something\ else\;\ break\;\}\ndefault\ \{if\ an\ error,\ say\ so\ and\ break\;\ do\ the\ last\ thing,\ break\;\}\n======\n\nIn\ tcl,\ one\ would\ recode\ using\ else\ or\ elseif\ or\ fiddling\ with\ state\ variables,\ etc.\ to\ accomplish\ the\ same\ thing.\n\n----\nA\ well\ known\ Tcl\ pundit\ suggested:\n======\n\ \ \ \ \$NOTFOUND\ \{\n\ \ \ \ \ \ \ \ puts\ \"page\ not\ found\ \"\n\ \ \ \ \}\n\ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ puts\ \"Program\ encountered\ code\ \$::errorCode\"\n\ \ \ \ \}\n\"\n======\nso\ that\ Tcl\ had\ a\ chance\ to\ substitue\ `\$NOTFOUND`.\nso\ that\ Tcl\ had\ a\ chance\ to\ substitue\ the\ value\ of\ \$NOTFOUND.\n''\[AMG\]:\ The\ quotes\ don't\ match\ up\ the\ way\ you\ expect.\ \ This\ is\ because\ braces\ inside\ \"quoted\"\ words\ don't\ have\ any\ special\ power.\ \ the\ second\ argument\ to\ switch\ starts\ with\ a\ line\ break,\ ends\ with\ the\ space\ following\ puts,\ and\ has\ the\ word\ \"page\"\ illegally\ appended\ to\ it,\ resulting\ in\ an\ \"extra\ characters\ after\ close-quote\"\ error.''\n\nHowever,\ the\ follow\ up,\ by\ \[Ken\ Jones\]\ said\ it\ best:\n\nyou\ don't\ want\ that\ (unless\ you're\ doing\ some\ very,\ very,\ very\ntricky\ stuff).\ Quoting\ switch's\ pattern/action\ block\ with\ `\"\"`\ allows\ntricky\ stuff).\ Quoting\ switch's\ pattern/action\ block\ with\ \"\"\ allows\nsubstitutions\ within\ the\ entire\ argument.\ So,\ yes\ you\ get\ the\ \$URL_NOT_FOUND\nvariable\ substituted.\ But\ you\ also\ get\ the\ contents\ of\ the\ actions\n\n\[lexfiend\]:\ I\ think\ the\ following\ example\ illustrates\ Ken's\ point\ better:\n\[lexfiend\]\ -\ I\ think\ the\ following\ example\ illustrates\ Ken's\ point\ better:\n#\ GOTCHA\ -\ You're\ dead\ no\ matter\ what\ you\ do\n\ #\ GOTCHA\ -\ You're\ dead\ no\ matter\ what\ you\ do\n\ set\ TriggerBomb\ 0\n\ set\ DefuseBomb\ 1\n\ set\ WaitAMinuteWhileIThinkThisThrough\ 2\n\ set\ Action\ \$WaitAMinuteWhileIThinkThisThrough\n\ interp\ alias\ \{\}\ SendToBomb\ \{\}\ puts\n\ switch\ \$Action\ \"\n\ \ \ \$TriggerBomb\ \{\n\ \ \ \ \ set\ result\ \[SendToBomb\ boom\]\n\ \ \ \}\n\ \ \ \$DefuseBomb\ \{\n\ \ \ \ \ set\ result\ \[SendToBomb\ shutdown\]\n\ \ \ \}\n\ \"\n\nInstead,\ we\ want\ the\ \"alternate\"\ syntax\ of\ switch,\ where\ you\ provide\ each\npattern\ and\ its\ corresponding\ action\ as\ separate\ arguments\ to\ switch,\nrather\ than\ as\ a\ monolithic\ pattern/action\ quoted\ argument.\ Here's\ a\n\nset\ NOTFOUND\ value\n\ set\ NOTFOUND\ \"value\"\n\ set\ errorCode\ \"nonsense\"\nswitch\ --\ \$::errorCode\ \\\n\ switch\ --\ \$::errorCode\ \\\n\ \ \ \ \$NOTFOUND\ \ \{\n\ \ \ \ \ \ \ \ puts\ \"page\ not\ found\"\n\ \ \ \ \ \ \ \ \}\ \\\n\ \ \ \ \ \ \ \ puts\ \"Program\ encountered\ code\ \$::errorCode\"\n\ \ \ \ \}\n======\n\n\[KBK\]\ -\ I\ dislike\ both\ of\ these.\ \ I\ tend\ to\ think\ of\ a\ switch\ as\ a\nconfuses\ me.\ \ I'd\ have\ just\ written:\n\nif\ \{\$::errorcode\ eq\ \$NOTFOUND\}\ \{\n\ \ if\ \{\ \[string\ equal\ \$::errorcode\ \$NOTFOUND\]\ \}\ \{\n\ \ \ \ \ \ puts\ \"page\ not\ found\"\n\ \ \}\ else\ \{\n\ \ \ \ \ \ puts\ \"Program\ encountered\ code\ \$::errorCode\"\n\ \ \}\n======\n\[RHS\]\ -\ I\ find\ that,\ when\ I\ need\ substitution\ for\ switch\ values,\ formatting\ it\ like\ the\ following\ looks\ cleaner:\n======\n\ switch\ --\ \$::errorCode\ \$NOTFOUND\ \{\n\ \ \ \ puts\ \"page\ not\ found\"\n\ \}\ \$value1\ \{\n\ \ \ \ puts\ \"blah\"\n\ \}\ default\ \{\n\}\n\ \}\n\n\[DKF\]:\ With\ 8.6,\ I'd\ be\ using\ \[try\]\ for\ this\ particular\ problem\ instead\ of\ using\ \[switch\]\ to\ pick\ through\ the\ \[errorCode\]\ after\ \[catch\]\ returned,\ but\ YMMV.\n\nThe\ above\ sample\ was,\ of\ course,\ intended\ to\ be\ brief,\ and\ didn't\ show\ the\ other\ several\ dozen\ switch\ cases\ .\ \ For\ a\ single\ comparison,\ I\ agree\ with\ KBK.\ \ But\ if\ I\ have\ more\ than\ one\ or\ two\ of\ these\ types\ of\ comparisons,\ then\ I\ know\ '''I'''\ \[LV\]\ prefer\ a\ switch.\n\[LV\]:\ The\ above\ sample\ was,\ of\ course,\ intended\ to\ be\ brief,\ and\ didn't\ show\ the\ other\ several\ dozen\ switch\ cases.\ \ For\ a\ single\ comparison,\ I\ agree\ with\ \[KBK\].\ \ But\ if\ I\ have\ more\ than\ one\ or\ two\ of\ these\ types\ of\ comparisons,\ then\ I\ know\ ''I''\ prefer\ a\ switch.\n\nWith\ '''switch\ -regexp''',\ you\ can\ specify\ abbreviations\ of\ a\ flag\ to\ be\ switched\ on\ like\ this:\nif\ 0\ \{\n\ switch\ -regexp\ --\ \$variable\ \{\n\ \ -h(e(lp?)?)?\ \ \ \ \ \ \ \ \ \ \ \ \ \{...\}\n\ \ -h|-he|-hel|-help|-ayuda\ \{...\}\n\ \ -\\\\?\ \{\ ...\ \}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;\$\ Match\ -?\ flag\n\ \ \"(?x)\ -\ |\ -h\ |\ -help\"\ \{do\ stuff\}\ \;#\ extended\ RE\ syntax\n\ \}\n\n\nswitch\ --\ \$variable\ \{\n\ switch\ --\ \$variable\ \{\n\ \ -h\ -\ -he\ -\ -hel\ -\ -help\ \{\ ...\ \}\n\ \}\n\n\n\[LV\]\ I\ really\ find\ using\ -\ as\ a\ seperator\ between\ switch\ case\ alternatives\ to\ be\ counter-intuitive\;\ \nnormally\ one\ uses\ |\ for\ that\ sort\ of\ thing\ .\n\[LV\]:\ I\ really\ find\ using\ `-`\ as\ a\ separator\ between\ switch\ case\ alternatives\ to\ be\ counter-intuitive\ .\n\nswitch\ --\ \$variable\ \{\n\ switch\ --\ \$variable\ \{\n\ \ \ \ -he\ \ \ -\ \n\ \ \ \ -hel\ \ -\ \n\ \ \ \ -help\ \{...\}\n\ \ \ \ -help\ \{\ ...\ \}\n\ \}\n\n\n----\n\[SB\],\ 2003-05-21:\ When\ I\ use\ switch\ -regexp,\ Tcl\ already\ use\ regexp\ once\ to\ enter\ the\ proper\ clause.\ How\ can\ the\ match\ pattern\ be\ accessed\ from\ within\ the\ clause,\ if\ possible,\ and\ is\ switch\ -regexp\ able\ to\ use\ ()\ match\ variables?\ I\ think\ perl\ store\ the\ regexp\ matches\ in\ global\ variables\ \$1\ ..\ \$9\ \n\nswitch\ -regexp\ --\ \$somevar\ \{\n\ switch\ -regexp\ --\ \$somevar\ \{\n\ \ \ \ \{^(\\d+)\\s+(\\d+)\}\ \{puts\ \"You\ hit\ number\ matches\ \$1\ and\ \$2\"\}\n\}\n\ \}\n\n\[KBK\]\ -\ You\ can't.\ \ However,\ that\ form\ of\ \[\[switch\]\]\ is\ no\ slower\ than\ the\ corresponding\ \[\[if\]\]...\[\[elseif\]\],\ \n\nif\ \{\[regexp\ \{^(\\S+)\\s+(\\S+)\$\}\ \$somevar\ ->\ part1\ part2\]\}\ \{\n\ \ \ if\ \{\ \[regexp\ \{^(\\S+)\\s+(\\S+)\$\}\ \$somevar\ ->\ part1\ part2\]\ \}\ \{\n\ \ \ \ \ \ \ \ puts\ \"You\ hit\ matches\ \$part1\ and\ \$part2\"\n\ \ \ \ \}\ elseif\ \{\ \[regexp\ \{^(\\d+)\\s+(\\d+)\}\ ->\ part1\ part2\]\ \}\ \{\n\ \ \ \ \ \ \ \ puts\ \"You\ hit\ number\ matches\ \$part1\ and\ \$part2\"\n\ \ \ \ \}\n\n\[hkoba\],\ 2005-03-18:\ Hmm,\ how\ about\ \[switch-regexp\]?\n\[hkoba\]\ 2005-03-18:\ Hmm,\ how\ about\ \[switch-regexp\]?\n\n----\nHow's\ this\ for\ a\ silly\ compromise.\ \nNicely\ aligns\ the\ dispatch\ conditions\ and\ removes\ the\ confusing\ barrage\ of\ backslashes.\n======\n\ if\ \{0\}\ \{\n\ \}\ elseif\ \{\$state\ ==\ \$INIT_STATE\}\ \{\n\n\ \ \ \ puts\ init\n\n\ \}\ elseif\ \{\$state\ ==\ \$CLEANING_STATE\}\ \{\n**\ Delimiting\ the\ Options\ **\n\ \ \ \ puts\ cleaning\n\[LES\]:\ So,\ if\ it\ is\ so\ good\ a\ practice\ ALWAYS\ to\ call\ switch\ as\ \"switch\ --\"\ (the\ switch\ to\ end\ all\ switches),\ why\ can't\ the\ core\ code\ already\ cope\ with\ that?\n\ \}\ elseif\ \{\$state\ ==\ \$DONE_STATE\}\ \{\n\n\ \ \ \ puts\ done\n\n\ \}\n======\n----\nThe\ silliness\ continues...\ this\ actually\ works\ though\ I'm\ not\ sure\ of\ the\ side\ effects.\n======\n\ proc\ dispatch\ \{thevar\ args\}\ \{\n\ \ \ \ \ set\ pass1\ \[uplevel\ subst\ \$args\]\n\ \ \ \ \ set\ pass2\ \"switch\ \\\$\$thevar\ \\\{\ \$pass1\ \\\}\"\n\ \ \ \ \ uplevel\ \$pass2\n\ \}\n\ \n\ set\ INIT_STATE\ \"init\"\n\ set\ CLEANING_STATE\ \"cleaning\"\n\ set\ DONE_STATE\ \"done\"\n\ \n\ set\ state\ \$INIT_STATE\n\ \n\ dispatch\ state\ \{\n\ \ \ \ \ \$INIT_STATE\ \{\n\ \n\ \ \ \ \ \ \ \ \ puts\ init\n\ \ \ \ \ \ \ \ \ set\ nextstate\ \$DONE_STATE\n\ \n\ \ \ \ \ \}\n\ \ \ \ \ \$CLEANING_STATE\ \{\n\ \n\ \ \ \ \ \ \ \ \ puts\ cleaning\n\ \n\ \ \ \ \ \}\n\ \ \ \ \ \$DONE_STATE\ \{\n\ \n\ \ \ \ \ \ \ \ \ puts\ done\n\ \n\ \ \ \ \ \}\n\ \ \ \ \ default\ \{\n\ \ \ \ \ \}\n\ \}\n\ puts\ \"next\ state\ \$nextstate\"\n======\n----\nSee\ also\ \[ranged\ switch\]\n\n----\n\n\[MG\]:\ That's\ not\ really\ specific\ to\ switch\ -\ it's\ really\ good\ practice\ with\ ''all''\ commands\ that\ take\ ''-something''\ args,\ and\ show\ the\ end\ of\ those\ with\ '--',\ to\ include\ the\ --.\ And\ I\ think\ the\ reason\ the\ core\ can't\ handle\ is\ that\ sometimes\ you\ may\ actually\ want\ the\ behaviour\ that\ occurs\ when\ you\ don't\ give\ `--`.\n\[MG\]\ That's\ not\ really\ specific\ to\ switch\ -\ it's\ really\ good\ practice\ with\ ''all''\ commands\ that\ take\ ''-something''\ args,\ and\ show\ the\ end\ of\ those\ with\ '--',\ to\ include\ the\ --.\ And\ I\ think\ the\ reason\ the\ core\ can't\ handle\ is\ that\ you\ may\ actually\ want\ the\ behaviour\ that\ occurs\ when\ you\ don't\ give\ --,\ some\ times.\ \n\[LV\]:\ because\ technically\ the\ rule\ isn't\ \"ALWAYS\ call\ switch\ as\ `switch\ --`\".\n\[LV\]\ because\ technically\ the\ rule\ isn't\ \"ALWAYS\ call\ switch\ as\ `switch\ --`\".\nThe\ rule\ is\ \"ALWAYS\ call\ switch\ with\ --\ after\ the\ last\ of\ the\ switch\nThink\ of\ code\ like\ this:\n\nset\ arg\ \{something\ entered\ by\ the\ user\}\n\ set\ arg\ \"something\ entered\ by\ the\ user\"\n\ switch\ \$arg\ \{\n\ \ \ \ \ \ \ \ --first_thing\ \{\ do\ something\ \}\n\ \ \ \ \ \ \ \ --second_thing\ \{\ do\ something\ else\ \}\n\ \ \ \ \ \ \ \ default\ \{do\ the\ last\ thing\ \}\n\ \}\n\nNow,\ if\ the\ user\ happens\ to\ type\ in\ \"--first_thing\",\ the\ program\n\n\ bad\ option\ \"--first_thing\":\ must\ be\ -exact,\ -glob,\ -regexp,\ or\ --\nbecause\ there\ was\ no\ \"--\"\ between\ the\ switch\ and\ the\ variable\ being\nexamined.\ Not\ only\ that,\ but\ if\ the\ user\ happens\ to\ type\ in\ \"-exact\",\n\n\ wrong\ #\ args:\ should\ be\ \"switch\ ?switches?\ string\ pattern\ body\ ...\ ?default\ body?\"\nbecause\ of\ the\ missing\ \"--\"\ .\ \ Two\ potential\ error\ situations\ -\ and\ncalled,\ any\ information\ about\ where\ the\ first\ argument\ is\ already\ gone.\n\n\[RS\]:\ The\ need\ for\ `--`\ seems\ to\ exist\ only\ for\ ''switch''.\ Other\ commands\ don't\ get\ confused\ by\ parameters\ that\ look\ like\ switches\ but\ aren't:\n\[RS\]\ The\ need\ for\ --\ seems\ to\ exist\ only\ for\ ''switch''.\ Other\ commands\ don't\ get\ confused\ by\ parameters\ that\ look\ like\ switches\ but\ aren't:\n\ %\ lsearch\ -foo\ -bar\n\ -1\nThen\ again,\ \[regexp\]\ has\ the\ same\ need\ for\ --:\n\ %\ regexp\ -foo\ -bar\n\ bad\ switch\ \"-foo\":\ must\ be\ -all,\ -about,\ -indices,\ -inline,\ -expanded,\ -line,\ -linestop,\ -lineanchor,\ -nocase,\ -start,\ or\ --\n======none\nYax:\ lsearch\ assumes\ the\ form\ of\ arguments\ by\ the\ argument\ count,\ and\ its\ quite\ probable\ that\ all\ commands\ that\ take\ fixed\ args\ after\ options\ do.\ Any\ commands\ (such\ as\ regexp)\ that\ can\ take\ an\ arbitrarily\ varying\ number\ of\ args\ and\ have\ switches\ probably\ also\ suffer\ this\ issue.\nThen\ again,\ `\[regexp\]`\ has\ the\ same\ need\ for\ `--`:\n----\n\[RS\]\ 2005-05-30:\ Unlike\ in\ \[C\],\ \[Tcl\]'s\ \[switch\]\ returns\ its\ last\ evaluated\ result,\ \nso\ it\ can\ be\ used\ as\ a\ function.\ Given\ this\ simple\ identity\n\n\ proc\ is\ x\ \{set\ x\}\n\n\nforeach\ num\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\ 7\ 8\ 9\}\ \{\n\ foreach\ num\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\ 7\ 8\ 9\}\ \{\n\ \ \ \ \ \ \ \ 1\ -\ 9\ \ \ \ \ \ \ \ \ \{is\ odd\}\n\ \ \ \ \ \ 1\ -\ 9\ \ \ \ \ \ \ \ \ \{is\ odd\}\n\ \ \ \ \ \ 2\ -\ 3\ -\ 5\ -\ 7\ \{is\ prime\}\n\ \ \ \ \ \ 0\ -\ 4\ -\ 6\ -\ 8\ \{is\ even\}\n\ \ \ \ puts\ \"\$num\ is\ \$type\"\n\}\n\ \}\n\n\n\ 0\ is\ even\n\ 1\ is\ odd\n\ 2\ is\ prime\n\ 3\ is\ prime\n\ 4\ is\ even\n\ 5\ is\ prime\n\ 6\ is\ even\n\ 7\ is\ prime\n\ 8\ is\ even\n\ 9\ is\ odd\n======none\n\[ZB\]\ 20100318\ -\ the\ above\ example\ doesn't\ work\ (invalid\ command\ name\ \"is\").\ I've\ got\ a\ feeling,\ it\ was\ probably\ valid\ for\ TCL8.4\ (didn't\ check\ it),\ but\ it\ won't\ work\ with\ 8.6\ anymore.\n\n\[Lars\ H\]:\ More\ likely,\ you\ forgot\ to\ include\ the\ definition\ of\ '''is'''\ (the\ proc\ command\ in\ the\ preceeding\ one-line\ code\ block).\n\n\[ZB\]\ Oh,\ yeah...\ O_O\ indeed.\n\n\[AMG\]:\ See\ \[return\]\ for\ more\ discussion\ of\ this\ pattern.\ \ Search\ for\ \"return\ -level\ 0\".\ \ I\ have\ found\ that\ the\ simplest\ way\ to\ do\ it\ is\ with\ single-argument\ \[lindex\].\ \ Elsewhere\ I've\ seen\ it\ done\ with\ single-argument\ \[list\],\ but\ this\ is\ unsafe.\n\n----\n\[LV\]\ Can\ someone\ help\ me\ with\ switch?\ I\ have\ what\ seems\ like\ a\ simple\nbit\ of\ code,\ but\ it\ doesn't\ work\ as\ I\ expected.\ So\ I\ need\ help\ adjusting\nmy\ expectation\ (and\ my\ code!).\n\n\ \$\ cat\ ts.tcl\n\ #!\ /usr/tcl84/bin/tclsh\n\[AMG\]:\ See\ \[identity\ function\ \]\ for\ more\ discussion\ of\ this\ pattern.\ \ The\ simplest\ way\ to\ do\ it\ is\ with\n\ set\ ::expert\ \"no\"\n\ set\ ::usage\ \"USAGE:\ \$argv0\ arg1\ arg2\"\n\ set\ ::val\ \"XYZ\"\n\n\ foreach\ i\ \$::argv\ \{\ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ switch\ -exact\ --\ \$i\ in\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ !\ \ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$::expert\ ==\ \"no\"\}\ \{\ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ ::expert\ \"yes\"\ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \$::usage\ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ exit\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n**\ History\ **\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 1\ \{\ set\ \$::val\ 1\ \}\nFirst\ announced\ by\ \[JO\]\ for\ Tcl\ 7.0\ in\ \[https://groups.google.com/d/msg/comp.lang.tcl/u1pATk0ytWM/8uStOsyBrLYJ%|%Advice\ wanted:\ \"case\"\ command\ and\ regexps\],\ \[comp.lang.tcl\],1993-06-05\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ default\ \{\ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"**\ Too\ many\ values\ specified\ **\"\ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"You\ will\ be\ prompted\ for\ the\ information\ **\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ ::expert\ \"no\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ \n\ \}\n\n\ puts\ \$::expert\n\ puts\ \$::val\n\ \$\ ts.tcl\ 1\ 2\ !\n\ no\n\ XYZ\n======\nI\ was\ expecting\ to\ see\ \n\n\ no\ \n\ **\ Too\ many\ values\ specified\ **\n\ You\ will\ be\ prompted\ for\ the\ information\ **\n\ 1\n**\ Compilation\ Notes\ **\nas\ a\ result,\ since\ I\ supplied\ a\ 2\ and\ a\ !.\n\[DKF\]:\ In\ Tcl\ \[Changes\ in\ Tcl/Tk\ 8.5%|%8.5\],\ `switch`\ is\ \[bytecode%|%byte-compiled\]\ if\ reasonably\ possible.\ The\ \"reasonably\ possible\"\ part\ means\ that\ you\ do\ have\ to\ be\ doing\ either\ '''`-exact`'''\ or\ '''`-glob`'''\ matching,\ and\ the\ bodies\ of\ the\ arms\ have\ to\ be\ compilable\ (as\ usual).\ With\ '''`-regexp`'''\ matching,\ that\ always\ goes\ to\ the\ \"interpreted\"\ version\ (though\ by\ compensation,\ there\ are\ some\ other\ new\ goodies\ (see\ `-matchvar`\ and\ `-indexvar`,\ for\ instance)\ available).\nWhat\ am\ I\ missing\ in\ this?\nIn\ most\ cases,\ the\ switch\ is\ compiled\ to\ (effectively)\ a\ sequence\ of\ `\[if\]`\ commands.\ However,\ in\ some\ special\ cases,\ i.e.\ '''`-exact`'''\ matching\ of\ constant\ terms,\ a\ jump\ table\ is\ built\ instead,\ which\ is\ considerably\ more\ efficient,\ especially\ for\ terms\ other\ than\ the\ first\ one.\n\[RHS\]\ You\ have\ an\ '''in'''\ there\ that\ you\ shouldn't:\n\ switch\ -exact\ --\ \$i\ in\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ^^\n\n----\n'''Compilation\ Notes'''\n**\ Bug:\ `-indexvar`\ Indexes\ Off\ By\ One\ **\n\[DKF\]:\ In\ Tcl\ 8.5,\ the\ '''switch'''\ command\ is\ bytecompiled\ if\ reasonably\ possible.\ The\ \"reasonably\ possible\"\ part\ means\ that\ you\ do\ have\ to\ be\ doing\ either\ '''-exact'''\ or\ '''-glob'''\ matching,\ and\ the\ bodies\ of\ the\ arms\ have\ to\ be\ compilable\ (as\ usual).\ With\ '''-regexp'''\ matching,\ that\ always\ goes\ to\ the\ \"interpreted\"\ version\ (though\ by\ compensation,\ there\ are\ some\ other\ new\ goodies\ (see\ -matchvar\ and\ -indexvar,\ for\ instance)\ available).\n\[TJE\]:\ Why\ are\ the\ ranges\ placed\ in\ a\ `switch`\ statement's\ `-indexvar`\ target\ inclusive\ of\ the\ character\ AFTER\ the\ match?\ \ This\ differs\ from\ the\ behavior\ of\ regexp's\ `-indices`\ option,\ which\ seems\ quite\ odd\ to\ me.\ \ For\ example:\nIn\ most\ cases,\ the\ switch\ is\ compiled\ to\ (effectively)\ a\ sequence\ of\ \[if\]s.\ However,\ in\ some\ special\ cases\ (i.e.\ '''-exact'''\ matching\ of\ constant\ terms)\ a\ jump\ table\ is\ built\ instead,\ which\ is\ considerably\ more\ efficient,\ especially\ for\ terms\ other\ than\ the\ first\ one.\n======\n----\n\[TJE\]\ Why\ are\ the\ ranges\ placed\ in\ a\ switch\ statement's\ \"-indexvar\"\ target\ inclusive\ of\ the\ character\ AFTER\ the\ match?\ \ This\ differs\ from\ the\ behavior\ of\ regexp's\ \"-indices\"\ option,\ which\ seems\ quite\ odd\ to\ me.\ \ For\ example:\n%\ set\ line\ \{foo\ bar\}\n\ \ %\ set\ line\ \{foo\ bar\}\n\ \ foo\ bar\n\ \ %\ regexp\ -inline\ -indices\ \{foo\}\ \$line\n\ \ \{0\ 2\}\n\ \ %\ switch\ -regexp\ -indexvar\ index\ --\ \$line\ \{foo\}\ \{set\ index\}\n\ \ \{0\ 3\}\n\n\n\[PYK\]\ 2014-05-30:\ If\ this\ really\ happened,\ it\ must\ have\ been\ a\ bug\ in\ some\n\n\[\[Anyone\ have\ an\ example\ of\ a\ switch\ statement\ with\ two\ or\ more\ cases,\ with\ comments\ for\ each\ case?\]\]\n\[Wookie\]:\ I\ have\ a\ large\ switch\ and\ wanted\ comments\ for\ blocks\ of\ statements\ e.g.\nThe\ man\ page\ \[http://www.tcl.tk/man/tcl8.5/TclCmd/switch.htm\]\ includes\ such\ an\ example.\n\n\nswitch\ -exact\ --\ \$test\ \{\n\ \ switch\ -exact\ --\ \$test\ \{\n\ \ \ \ Test1\ \{do\ stuff...\}\n\ \ \ \ Test1\ \{\ SomeProcs...\}\n\ \ \ \ Test2\ \{\ SomeProcs...\}\n\n\ \ \ \ Test3\ \{do\ stuff...\}\n\ \ \ \ Test3\ \{\ SomeProcs...\}\n\ \ \ \ Test4\ \{\ SomeProcs...\}\n\n\ \ \ \ NONE\ -\n\ \ \ \ default\ \{SomeCleanUpProc...\}\n\ \ \ \ default\ \{\ SomeCleanUpProc...\ \}\n\ \ \}\n\n\ \ \ \"extra\ switch\ pattern\ with\ no\ body,\ this\ may\ be\ due\ to\ a\ comment\ incorrectly\ placed\ outside\ of\ a\ switch\ body\ -\ see\ the\ \"switch\"\ documentation\"\n\nAs\ Tcl\ `switch`\ statements\ don't\ seem\ to\ care\ that\ there\ are\ multiple\ definitions\ of\ a\ statement,\ I\ rewrote\ the\ code\ as:\ \nAs\ TCL\ switch\ statements\ don't\ seem\ to\ care\ that\ there\ are\ multiple\ definitions\ of\ a\ statement,\ I\ rewrote\ the\ code\ as:\ \nswitch\ -exact\ --\ \$test\ \{\n\ \ switch\ -exact\ --\ \$test\ \{\n\ \ \ \ Test1\ \{do\ stuff...\}\n\ \ \ \ Test1\ \{\ SomeProc...\}\n\ \ \ \ Test2\ \{\ SomeProc...\}\n\n\ \ \ \ Test3\ \{do\ stuff...\}\n\ \ \ \ Test3\ \{\ SomeProc...\}\n\ \ \ \ Test4\ \{\ SomeProc...\}\n\n\ \ \ \ NONE\ -\n\ \ \ \ default\ \{clean\ up\ stuff...\}\n\ \ \ \ default\ \{\ SomeCleanUpProc...\ \}\n\ \ \}\ \n\n\n----\n\[DrASK\]\ -\ Is\ there\ any\ speed\ improvement\ when\ using\ -exact\ over\ -regexp?\ As\ in:\nset\ number\ 0x5\n\ \ \ switch\ -exact\ --\ \$value\ \{\n\ \ \ \ \ \ \{a\}\ -\ \{b\}\ -\ \{c\}\ \{match\}\n\ \ \ \}\nYou\ may\ instead\ consider\ a\ long\ `\[if\]`/`\[elseif\]`\ chain,\ but\ maybe\ this\ won't\ \[bytecode\]\ as\ well.\ \ Alternately,\ force\ the\ \[format%|%formatting\]\ to\ be\ consistent:\n\ \ \ switch\ -regexp\ --\ \$value\ \{\n\ \ \ \ \ \ \{\[abc\]\}\ \{match\}\n\ \ \ \}\nset\ number\ 0x5\n\[Lars\ H\]:\ Comments\ by\ '''DKF'''\ above\ suggest\ that\ the\ answer\ should\ be\ yes,\ but\ why\ not\ check\ for\ yourself?\ \[time\]\ it!\n\n\nswitch\ -regexp\ --\ \$value\ \{\n\ \ \ switch\ -regexp\ --\ \$value\ \{\n\ \ \ \ \ \ \{^\[abc\]\$\}\ \{match\}\n\ \ \ \}\n\n\[DrASK\]\ Yeah,\ I\ failed\ to\ mention\ that\ \$value\ is\ known\ to\ be\ a\ single\ character.\ Thanks.\ Here\ is\ the\ test\ and\ the\ results:\nproc\ exact\ value\ \{\n\ proc\ exact\ \{value\}\ \{\n\ \ \ \ \ \ \ \ a\ -\ b\ -\ c\ \{return\ true\}\n\ \ \ \ \ \ \ \ default\ \{return\ false\}\n\ \ \ \ \}\n\}\n\ \}\nproc\ re\ value\ \{\n\ proc\ regexp\ \{value\}\ \{\n\ \ \ \ \ \ \ \ \[abc\]\ \{return\ true\}\n\ \ \ \ \ \ \ \ \{\[abc\]\}\ \{return\ true\}\n\ \ \ \ \}\n\}\n\ \}\nproc\ first\ value\ \{\n\ proc\ first\ \{value\}\ \{\n\ \ \ \ return\ \[expr\ \{\[string\ match\ \$value\ \{abc\}\]\ !=\ -1\}\]\n\ \}\nproc\ multi\ \{type\ value\}\ \{\n\ proc\ multi\ \{type\ value\}\ \{\n\ \ \ \ \ \ \ \ \$type\ \$value\n\ \ \ \ \}\n\}\n\ \}\nforeach\ type\ \{exact\ re\ first\}\ \{\n\ foreach\ type\ \{exact\ regexp\ first\}\ \{\n\ \ \ \ \ \ \ \ puts\ \"\$type\ \$value\ \[errortime\ \{multi\ \$type\ \$value\}\ 10000\ 100\]\"\n\ \ \ \ \}\n\}\n\ \}\n\ \n\ exact\ a\ 66\ +/-\ 0\ microseconds\ per\ iteration\n\ exact\ b\ 67\ +/-\ 0\ microseconds\ per\ iteration\n\ exact\ c\ 67\ +/-\ 0\ microseconds\ per\ iteration\n\ exact\ d\ 66\ +/-\ 0\ microseconds\ per\ iteration\n\ regexp\ a\ 151\ +/-\ 0\ microseconds\ per\ iteration\n\ regexp\ b\ 140\ +/-\ 0\ microseconds\ per\ iteration\n\ regexp\ c\ 142\ +/-\ 0\ microseconds\ per\ iteration\n\ regexp\ d\ 121\ +/-\ 0\ microseconds\ per\ iteration\n\ first\ a\ 71\ +/-\ 0\ microseconds\ per\ iteration\n\ first\ b\ 71\ +/-\ 0\ microseconds\ per\ iteration\n\ first\ c\ 71\ +/-\ 0\ microseconds\ per\ iteration\n\ first\ d\ 70\ +/-\ 0\ microseconds\ per\ iteration\n======none\nIt's\ interesting\ to\ note\ the\ dropoff\ when\ regexp\ hit\ the\ default\ case.\ But\ -regexp\ is\ clearly\ is\ 2-2.5x\ slower.\ I\ used\ \[MAK\]'s\ errortime\ proc\ \[http://wiki.tcl.tk/924\]\ for\ timing.\nIt's\ interesting\ to\ note\ the\ dropoff\ when\ `\[regexp\]`\ hit\ the\ default\ case.\ But\ `-regexp`\ is\ clearly\ is\ 2-2.5x\ slower.\ I\ used\ \[MAK\]'s\ \[How\ to\ Measure\ Performance%|%errortime\ proc\]\ for\ timing.\n\[ferrieux\]:\ Indeed,\ timing\ shows\ that\ the\ jump\ table\ is\ roughly\ 3x\ faster\ than\ if..elseif..elseif,\ which\ is\ itself\ 1.25x\ faster\ than\ regexp.\ Notice\ that\ the\ regexp\ compilation\ overhead\ is\ not\ in\ the\ picture,\ since\ it\ is\ cached.\ Not\ sure\ whether\ we\ should\ worry\ about\ the\ 1.25...\n\[ferrieux\]:\ Indeed,\ timing\ shows\ that\ the\ jump\ table\ is\ roughly\ 3x\ faster\ than\ `if..elseif..elseif`,\ which\ is\ itself\ 1.25x\ faster\ than\ `\[regexp\]`.\ Notice\ that\ the\ `\[regexp\]`\ compilation\ overhead\ is\ not\ in\ the\ picture,\ since\ it\ is\ cached.\ Not\ sure\ whether\ we\ should\ worry\ about\ the\ 1.25...\n----\n\[AMG\]:\ Unlike\ \[C\]\ switch\ which\ does\ numeric\ comparisons,\ \[Tcl\]\ switch\ performs\ string\ comparisons.\ \ This\ can\ make\ a\ big\ difference\ in\ your\ program\ if\ you\ are\ dealing\ with\ numbers\ that\ are\ formatted\ in\ different\ ways.\n\n======\nset\ number\ 0x5\nswitch\ --\ \$number\ \{\n5\ \ \ \ \ \ \ \{puts\ five!\}\ndefault\ \{puts\ unknown\}\n\}\n======\n**\ An\ Implementation\ in\ Tcl\ **\nYou\ may\ instead\ consider\ a\ long\ \[if\]/\[elseif\]\ chain,\ but\ maybe\ this\ won't\ \[bytecode\]\ as\ well.\ \ Alternately,\ force\ the\ \[format\]ting\ to\ be\ consistent:\n\[rwm\]:\ I\ recently\ needed\ to\ run\ some\ \[Changes\ in\ Tcl/Tk\ 8.5%|%8.5\]\ code\ in\ \[Changes\ in\ Tcl/Tk\ 8.4%|%8.4\].\ \ I\ wrote\ the\ following\ code\ to\ mimic\ the\ 8.5\ switch\ in\ 8.4.\ (I\ looked\ for\ but\ could\ not\ find\ a\ compatibility\ library...)\ Note\ the\ many\ errors\ for\ cases\ that\ I\ did\ not\ need.\ \ Maybe\ someone\ else\ will\ cover\ fix/post\ those\ \;)\ \ Feel\ free\ to\ edit/move\ this\ as\ appropriate.\n======\nset\ number\ 0x5\nswitch\ --\ \[format\ %d\ \$number\]\ \{\n5\ \ \ \ \ \ \ \{puts\ five!\}\ndefault\ \{puts\ unknown\}\n\}\n======\n======\n----\n\[rwm\]:\ I\ recently\ needed\ to\ run\ some\ 8.5\ code\ in\ 8.4.\ \ I\ wrote\ the\ following\ code\ to\ mimic\ the\ 8.5\ switch\ in\ 8.4.\ (I\ looked\ for\ but\ could\ not\ find\ a\ compatibility\ library...)\ Note\ the\ many\ errors\ for\ cases\ that\ I\ did\ not\ need.\ \ Maybe\ someone\ else\ will\ cover\ fix/post\ those\ \;)\ \ Feel\ free\ to\ edit/move\ this\ as\ appropriate.\n\nproc\ switch_8.5\ args\}\ \{\nproc\ switch_8.5\ \{args\}\ \{\n\ \ \ ##\ this\ is\ an\ 8.4\ version\ of\ the\ 8.5\ switch\ (incomplete)\n\ \ \ if\ \{\[llength\ \$args\]\ <\ 2\}\ \{\n\ \ \ \ \ \ error\ \"usage:\ switch\ ?options?\ string\ \{pattern\ body\ ?pattern\ body\ ...?\}\"\n\ \ \ \}\n\ \ \ set\ type\ exact\n\ \ \ while\ \{\[string\ match\ \"-*\"\ \[lindex\ \$args\ 0\]\]\}\ \{\n\ \ \ \ \ \ set\ option\ \[lindex\ \$args\ 0\]\n\ \ \ \ \ \ set\ args\ \[lrange\ \$args\ 1\ end\]\n\ \ \ \ \ \ switch\ --\ \$option\ \{\n\ \ \ \ \ \ \ \ \ -exact\ \ \ \ \{set\ type\ exact\}\n\ \ \ \ \ \ \ \ \ -nocase\ \ \ \{set\ type\ nocase\}\n\ \ \ \ \ \ \ \ \ -glob\ \ \ \ \ \{set\ type\ glob\}\n\ \ \ \ \ \ \ \ \ -regexp\ \ \ \{set\ type\ regexp\}\n\ \ \ \ \ \ \ \ \ -matchvar\ \{set\ matchvar\ \[lindex\ \$args\ 0\]\;\ set\ args\ \[lrange\ \$args\ 1\ end\]\}\n\ \ \ \ \ \ \ \ \ -indexvar\ \{error\ \"unimplemented\"\}\n\ \ \ \ \ \ \ \ \ --\ \{break\}\n\ \ \ \ \ \ \ \ \ default\ \{error\ \"bad\ switch\ option=\$option\"\}\n\ \ \ \ \ \ \}\n\ \ \ \}\n\ \ \ set\ string\ \[lindex\ \$args\ 0\]\n\ \ \ if\ \{\[llength\ \$args\]\ ==\ 2\}\ \{\n\ \ \ \ \ \ set\ body\ \[lindex\ \$args\ 1\]\n\ \ \ \}\ else\ \{\ \n\ \ \ \ \ \ set\ body\ \[lrange\ \$args\ 1\ end\]\n\ \ \ \}\n\ \ \ switch\ --\ \$type\ \{\n\ \ \ \ \ \ exact\ \ \{error\ \"unimplemented\"\}\n\ \ \ \ \ \ nocase\ \{error\ \"unimplemented\"\}\n\ \ \ \ \ \ glob\ \ \ \{error\ \"unimplemented\"\}\n\ \ \ \ \ \ regexp\ \{\n\ \ \ \ \ \ \ \ \ foreach\ \{rexp\ script\}\ \$body\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\ \$rexp\ ==\ \"default\"\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ uplevel\ 1\ \$script\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[regexp\ --\ \$rexp\ \$string\ match\ 1\ 2\ 3\ 4\ 5\ 6\ 7\ 8\ 9\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[info\ exists\ matchvar\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ upvar\ \$matchvar\ m\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ m\ \[list\ \$match\ \$1\ \$2\ \$3\ \$4\ \$5\ \$6\ \$7\ \$8\ \$9\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ uplevel\ 1\ \$script\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ unset\ m\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ uplevel\ 1\ \$script\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \}\n\ \ \ \ \ \ default\ \{error\ \"internal\ type=\$type\ error\"\}\n\ \ \ \}\n======\n\n----\n\[neb\]\ ddd\ asked\ about\ http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/b6c3591dbbbf2b40?hl=en%|%extending\ switch\ statements%|%.\ I'm\ putting\ some\ of\ the\ answers\ here,\ because\ I\ intend\ to\ possibly\ use\ them\ =\]\n\nSchelte\ Bron\ said:\ The\ switch\ command\ (at\ least\ in\ the\ format\ you\ used)\ takes\ a\ list\ as\ its\ last\ argument.\ So\ you\ can\ simply\ put\ that\ into\ a\ variable\ and\ use\ the\ normal\ list\ operations\ to\ manipulate\ it:\nset\ switch\ \{\n\ \ \ a*b\ \ \ \ \ -\n\ \ \ b\ \ \ \ \ \ \ \{expr\ 1\}\n\ \ \ b\ \ \ \ \ \ \ \{expr\ \{1\}\}\n\ \ \ a*\ \ \ \ \ \ \{expr\ \{2\}\}\n\ \ \ default\ \{expr\ \{3\}\}\n\nswitch\ -glob\ aaab\ \$switch\n\nset\ switch\ \[linsert\ \$switch\ end-2\ c\ \{expr\ 4\}\]\nset\ switch\ \[linsert\ \$switch\ end-2\ c\ \{expr\ \{4\}\}\]\nswitch\ -glob\ c\ \$switch\n======\n\ndkf\ said:\ I'd\ do\ it\ like\ this,\ using\ the\ alternate\ form\ of\ \[switch\]:\nset\ defs\ \{\n\ \ set\ defs\ \{\n\ \ \ \ \ \ a*b\ \ \ \ \ -\n\ \ \ \ \ \ b\ \ \ \ \ \ \ \{expr\ \{1\}\}\n\ \ \ \ \ \ a*\ \ \ \ \ \ \{expr\ \{2\}\}\n\ \ \}\nswitch\ -glob\ --\ \$value\ \{*\}\$defs\ default\ \{\n\ \ switch\ -glob\ --\ \$value\ \{*\}\$defs\ default\ \{\n\ \ \ \ \ \ expr\ \{3\}\n\ \ \}\n\n\nlappend\ defs\ c\ \{expr\ 4\}\n\ \ lappend\ defs\ c\ \{expr\ \{4\}\}\n\nYet\ you\ won't\ disrupt\ the\ special\ handling\ of\ 'default',\ which\ has\ to\ be\ the\ last\ clause.\ (You\ could\ also\ put\ the\ default\ handling\ script\ in\ its\ own\ variable,\ or\ other\ arbitrarily\ complex\ solution.\ Your\ call.)\ \nYet\ you\ won't\ disrupt\ the\ special\ handling\ of\ `default`,\ which\ has\ to\ be\ the\ last\ clause.\ (You\ could\ also\ put\ the\ default\ handling\ script\ in\ its\ own\ variable,\ or\ other\ arbitrarily\ complex\ solution.\ Your\ call.)\ \n<<discussion>>\n----\n!!!!!!\n%|\ \[Category\ Command\]\ |\ \[Category\ Control\ Structure\]\ |%\n\[Tcl\ syntax\ help\]\ |\ \[Arts\ and\ crafts\ of\ Tcl-Tk\ programming\]\n!!!!!! regexp2} CALL {my render switch Documentation\ for\ the\ Tcl\ switch\ command\ can\ be\ found\ at\nhttp://www.purl.org/tcl/home/man/tcl8.5/TclCmd/switch.htm\ \n\nHistory\ corner:\ First\ announced\ by\ \[JO\]\ for\ Tcl\ 7.0\ in\ \[http://groups.google.com/groups?q=group:comp.lang.tcl+author:ousterhout&start=800&hl=de&lr=&newwindow=1&scoring=d&selm=1t8s4g%24kfs%40agate.berkeley.edu&rnum=840\]\n\nThere\ is\ a\ typo\ in\ the\ current\ switch.html\ documenation.\ \ It\ should\ read:\n======\n\ \ \ \ switch\ abc\ \"a\ -\ b\"\ \{expr\ \{1\}\}\ \$foo\ \{expr\ \{2\}\}\ default\ \{expr\ \{3\}\}\n======\n'''switch'''\ supersedes\ \[\[\[case\]\]\].\n**\ Synopsis\ **\n<<discussion>>\n\[RS\]\ Make\ sure\ you\ always\ write\ \"the\ switch\ to\ end\ all\ switches\",\ \"--\",\ if\ there\ is\ \nthe\ slightest\ possibility\ that\ faulty\ or\ unexpected\ data\ (i.e.,\ beginning\ with\ a\ dash)\ \nmay\ occur\ -\ they\ raise\ a\ data-driven\ syntax\ error\ which\ does\ not\ make\ a\ good\ impression\ on\ end-users.\n\ switch\ --\ \$foo\ \{...\}\ \ \;#\ robust\ for\ all\ values\ of\ foo\nIn\ Tcl\ versions\ prior\ to\ \[Changes\ in\ Tcl/Tk\ 8.5%|%8.5\],\ \ `--`\ should\ be\ used\n\[AMG\]:\ Actually,\ \"--\"\ is\ not\ required\ when\ using\ this\ form\ of\ \[\[switch\]\]\ \[http://www.tcl.tk/man/tcl8.6/TclCmd/switch.htm#M11\].\ \ It's\ only\ needed\ when\ the\ patterns\ and\ bodies\ are\ separate\ arguments,\ which\ is\ a\ relatively\ rare\ usage\ of\ \[\[switch\]\].\nWith\ exactly\ one\ argument,\ that\ argument\ is\ a\ \[dict%|%dictionary\]\ of\ patterns\n\[AMG\],\ update:\ On\ second\ thought,\ \"--\"\ is\ required,\ if\ you're\ using\ Tcl\ 8.4\ or\ older.\ \ Tcl\ 8.5+\ doesn't\ require\ it.\n\n----\nIn\ the\ form\ of\ the\ switch\ command\ where\ all\ patterns\ and\ bodies\ are\ in\ the\ last\ argument,\ this\ argument\ is\ technically\ a\ string\ which\ will\ be\ parsed\ by\ Tcl\ as\ a\ list.\ The\ rules\ for\ how\ a\ string\ is\ parsed\ as\ a\ list\ can\ be\ found\ on\ the\ \[lindex\]\ manual\ page\ \[http://www.purl.org/tcl/home/man/tcl8.5/TclCmd/lindex.htm\].\nThe\ difference\ here\ between\ a\ whitespace-delimited\ substring\ and\ a\ list\ element\ parsed\ from\ a\ string\ is\ usually\ negligible,\ but\ one\ must\ sometimes\ take\ them\ into\ account\ to\ get\ the\ right\ amount\ of\ quoting\ in\ place.\ \nRegexp\ patterns\ are\ particularly\ easy\ to\ overquote.\n`switch`\ only\ performs\ string\ comparison,\ so\ it\ isn't\ ideal\ for\ numeric\n----\nCoding\ style\ for\ switch\ is\ tricky.\ \ Recently\ on\ comp.lang.tcl\ there\ was\nan\ exchange\ about\ getting\ switch\ to\ work\ right.\ \ The\ user\ had\ originally\n\nswitch\ \$::errorCode\ \{\n\ \ \ \ \$NOTFOUND\ \{\n\ \ \ \ \ \ \ \ puts\ \{page\ not\ found\}\n\ \ \ \ \ \ \ \ puts\ \"page\ not\ found\ \"\n\ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ puts\ \"Program\ encountered\ code\ \$::errorCode\"\n\ \ \ \ \ \ \ \ break\n\ \ \ \ \}\n\}\n======\n\n\n\[PYK\]\ 2014-05-29:\ \[scripted\ list\]\ can\ make\ this\ syntax\ work,\ and\ even\ allows\ comments:\n----\n\[PZ\]\ 'default'\ alternative\ for\ regexp:\n======\nset\ a\ x\nswitch\ -regexp\ --\ \$a\ \{\n\ \ \ \ \ \ \ \ \ y\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"y\"\n\ \ \ \ \ \ \ \ \ \}\n\ \n\ \ \ \ \ \ \ \ \ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"z\"\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"\$a\"\n\ \ \ \ \ \ \ \ \ \}\n\}\n======\nreturns:\n======\n\ z\n\n----\n\[LV\]\ When\ I\ try\ to\ use\ a\ break\ inside\ of\ a\ switch\ command,\ I\ get\ the\ error\n\nswitch\ \$::errorCode\ \[sl\ \{\ninvoked\ \"break\"\ outside\ of\ a\ loop\n\ \ \ \ while\ executing\n\"switch\ \n\nA\ well-known\ Tcl\ pundit\ suggested:\nIs\ there\ an\ equivalent\ to\ \[break\]\ for\ switch?\n======\n\[YSK\]\ How\ about\ trapping\ \"switch\"\ in\ \"while\ 1\":\n\nswitch\ \$::errorCode\ \"\nwhile\ \{1\}\ \{\nswitch\ \$cond\ \{\ncase1\ \{\n\ \ \ if\ \{\$fault\}\ \{puts\ NG\;\ break\}\n\ \ \ puts\ OK\ \ \ \ \n\}\ndefault\ \{\n\ \ \ puts\ OK\n\}\nbreak\n\}\n======\n\n\[MG\]\ Hrm,\ I\ thought\ \[break\]\ worked\ in\ switches,\ too.\ But\ it\ seems\ that\ Tcl's\ \[switch\]\ doesn't\ fall\ through\ by\ default:\n\n======\nswitch\ -glob\ --\ foo\ \\\n\ \ f*\ \{puts\ match1\}\ \\\n\ \ *o*\ \{puts\ match2\}\ \\\n\ \ default\ \{puts\ nomatch\}\n======\n\nOnly\ the\ \"match1\"\ is\ shown,\ and\ then\ it\ stops,\ there's\ no\ \"match2\".\ So\ no\ \[break\]\ is\ needed,\ it'll\ stop\ when\ a\ match\ is\ found\ anyway.\ That\ means,\ in\ something\ like\n\n======\nswitch\ -glob\ --\ \$string\ \\\n\ \ f*\ \{puts\ foo\}\n\ \ b*\ \{puts\ bar\}\n\ \ *z*\ \{#\ do\ nothing\}\n\ \ default\ \{puts\ \"something\ else\"\}\n======\n\nthe\ \"#\ do\ nothing\"\ case\ has\ the\ same\ effect\ as\ a\ \[break\]\ in\ a\ switch\ in\ \[C\]\ would.\n\n\[LV\]\ without\ break,\ it\ means\ that\ one\ has\ to\ code\ carefully\ to\ avoid\ the\ cases\ where\ one\ normally\ would\ use\ it.\ For\ instance,\ in\ other\ languages,\ one\ might\ code\n\n======\nswitch\ \$variable\ \{\ncase1\ \{do\ this\;\ break\}\ncase2\ \{do\ that\;\ break\}\ncase3\ \{if\ today\ is\ Monday,\ do\ the\ other\;\ break\;\ if\ tomorrow\ is\ the\ 14th,\ do\ something\ else\;\ break\;\}\ndefault\ \{if\ an\ error,\ say\ so\ and\ break\;\ do\ the\ last\ thing,\ break\;\}\n======\n\nIn\ tcl,\ one\ would\ recode\ using\ else\ or\ elseif\ or\ fiddling\ with\ state\ variables,\ etc.\ to\ accomplish\ the\ same\ thing.\n\n----\nA\ well\ known\ Tcl\ pundit\ suggested:\n======\n\ \ \ \ \$NOTFOUND\ \{\n\ \ \ \ \ \ \ \ puts\ \"page\ not\ found\ \"\n\ \ \ \ \}\n\ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ puts\ \"Program\ encountered\ code\ \$::errorCode\"\n\ \ \ \ \}\n\"\n======\nso\ that\ Tcl\ had\ a\ chance\ to\ substitue\ `\$NOTFOUND`.\nso\ that\ Tcl\ had\ a\ chance\ to\ substitue\ the\ value\ of\ \$NOTFOUND.\n''\[AMG\]:\ The\ quotes\ don't\ match\ up\ the\ way\ you\ expect.\ \ This\ is\ because\ braces\ inside\ \"quoted\"\ words\ don't\ have\ any\ special\ power.\ \ the\ second\ argument\ to\ switch\ starts\ with\ a\ line\ break,\ ends\ with\ the\ space\ following\ puts,\ and\ has\ the\ word\ \"page\"\ illegally\ appended\ to\ it,\ resulting\ in\ an\ \"extra\ characters\ after\ close-quote\"\ error.''\n\nHowever,\ the\ follow\ up,\ by\ \[Ken\ Jones\]\ said\ it\ best:\n\nyou\ don't\ want\ that\ (unless\ you're\ doing\ some\ very,\ very,\ very\ntricky\ stuff).\ Quoting\ switch's\ pattern/action\ block\ with\ `\"\"`\ allows\ntricky\ stuff).\ Quoting\ switch's\ pattern/action\ block\ with\ \"\"\ allows\nsubstitutions\ within\ the\ entire\ argument.\ So,\ yes\ you\ get\ the\ \$URL_NOT_FOUND\nvariable\ substituted.\ But\ you\ also\ get\ the\ contents\ of\ the\ actions\n\n\[lexfiend\]:\ I\ think\ the\ following\ example\ illustrates\ Ken's\ point\ better:\n\[lexfiend\]\ -\ I\ think\ the\ following\ example\ illustrates\ Ken's\ point\ better:\n#\ GOTCHA\ -\ You're\ dead\ no\ matter\ what\ you\ do\n\ #\ GOTCHA\ -\ You're\ dead\ no\ matter\ what\ you\ do\n\ set\ TriggerBomb\ 0\n\ set\ DefuseBomb\ 1\n\ set\ WaitAMinuteWhileIThinkThisThrough\ 2\n\ set\ Action\ \$WaitAMinuteWhileIThinkThisThrough\n\ interp\ alias\ \{\}\ SendToBomb\ \{\}\ puts\n\ switch\ \$Action\ \"\n\ \ \ \$TriggerBomb\ \{\n\ \ \ \ \ set\ result\ \[SendToBomb\ boom\]\n\ \ \ \}\n\ \ \ \$DefuseBomb\ \{\n\ \ \ \ \ set\ result\ \[SendToBomb\ shutdown\]\n\ \ \ \}\n\ \"\n\nInstead,\ we\ want\ the\ \"alternate\"\ syntax\ of\ switch,\ where\ you\ provide\ each\npattern\ and\ its\ corresponding\ action\ as\ separate\ arguments\ to\ switch,\nrather\ than\ as\ a\ monolithic\ pattern/action\ quoted\ argument.\ Here's\ a\n\nset\ NOTFOUND\ value\n\ set\ NOTFOUND\ \"value\"\n\ set\ errorCode\ \"nonsense\"\nswitch\ --\ \$::errorCode\ \\\n\ switch\ --\ \$::errorCode\ \\\n\ \ \ \ \$NOTFOUND\ \ \{\n\ \ \ \ \ \ \ \ puts\ \"page\ not\ found\"\n\ \ \ \ \ \ \ \ \}\ \\\n\ \ \ \ \ \ \ \ puts\ \"Program\ encountered\ code\ \$::errorCode\"\n\ \ \ \ \}\n======\n\n\[KBK\]\ -\ I\ dislike\ both\ of\ these.\ \ I\ tend\ to\ think\ of\ a\ switch\ as\ a\nconfuses\ me.\ \ I'd\ have\ just\ written:\n\nif\ \{\$::errorcode\ eq\ \$NOTFOUND\}\ \{\n\ \ if\ \{\ \[string\ equal\ \$::errorcode\ \$NOTFOUND\]\ \}\ \{\n\ \ \ \ \ \ puts\ \"page\ not\ found\"\n\ \ \}\ else\ \{\n\ \ \ \ \ \ puts\ \"Program\ encountered\ code\ \$::errorCode\"\n\ \ \}\n======\n\[RHS\]\ -\ I\ find\ that,\ when\ I\ need\ substitution\ for\ switch\ values,\ formatting\ it\ like\ the\ following\ looks\ cleaner:\n======\n\ switch\ --\ \$::errorCode\ \$NOTFOUND\ \{\n\ \ \ \ puts\ \"page\ not\ found\"\n\ \}\ \$value1\ \{\n\ \ \ \ puts\ \"blah\"\n\ \}\ default\ \{\n\}\n\ \}\n\n\[DKF\]:\ With\ 8.6,\ I'd\ be\ using\ \[try\]\ for\ this\ particular\ problem\ instead\ of\ using\ \[switch\]\ to\ pick\ through\ the\ \[errorCode\]\ after\ \[catch\]\ returned,\ but\ YMMV.\n\nThe\ above\ sample\ was,\ of\ course,\ intended\ to\ be\ brief,\ and\ didn't\ show\ the\ other\ several\ dozen\ switch\ cases\ .\ \ For\ a\ single\ comparison,\ I\ agree\ with\ KBK.\ \ But\ if\ I\ have\ more\ than\ one\ or\ two\ of\ these\ types\ of\ comparisons,\ then\ I\ know\ '''I'''\ \[LV\]\ prefer\ a\ switch.\n\[LV\]:\ The\ above\ sample\ was,\ of\ course,\ intended\ to\ be\ brief,\ and\ didn't\ show\ the\ other\ several\ dozen\ switch\ cases.\ \ For\ a\ single\ comparison,\ I\ agree\ with\ \[KBK\].\ \ But\ if\ I\ have\ more\ than\ one\ or\ two\ of\ these\ types\ of\ comparisons,\ then\ I\ know\ ''I''\ prefer\ a\ switch.\n\nWith\ '''switch\ -regexp''',\ you\ can\ specify\ abbreviations\ of\ a\ flag\ to\ be\ switched\ on\ like\ this:\nif\ 0\ \{\n\ switch\ -regexp\ --\ \$variable\ \{\n\ \ -h(e(lp?)?)?\ \ \ \ \ \ \ \ \ \ \ \ \ \{...\}\n\ \ -h|-he|-hel|-help|-ayuda\ \{...\}\n\ \ -\\\\?\ \{\ ...\ \}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;\$\ Match\ -?\ flag\n\ \ \"(?x)\ -\ |\ -h\ |\ -help\"\ \{do\ stuff\}\ \;#\ extended\ RE\ syntax\n\ \}\n\n\nswitch\ --\ \$variable\ \{\n\ switch\ --\ \$variable\ \{\n\ \ -h\ -\ -he\ -\ -hel\ -\ -help\ \{\ ...\ \}\n\ \}\n\n\n\[LV\]\ I\ really\ find\ using\ -\ as\ a\ seperator\ between\ switch\ case\ alternatives\ to\ be\ counter-intuitive\;\ \nnormally\ one\ uses\ |\ for\ that\ sort\ of\ thing\ .\n\[LV\]:\ I\ really\ find\ using\ `-`\ as\ a\ separator\ between\ switch\ case\ alternatives\ to\ be\ counter-intuitive\ .\n\nswitch\ --\ \$variable\ \{\n\ switch\ --\ \$variable\ \{\n\ \ \ \ -he\ \ \ -\ \n\ \ \ \ -hel\ \ -\ \n\ \ \ \ -help\ \{...\}\n\ \ \ \ -help\ \{\ ...\ \}\n\ \}\n\n\n----\n\[SB\],\ 2003-05-21:\ When\ I\ use\ switch\ -regexp,\ Tcl\ already\ use\ regexp\ once\ to\ enter\ the\ proper\ clause.\ How\ can\ the\ match\ pattern\ be\ accessed\ from\ within\ the\ clause,\ if\ possible,\ and\ is\ switch\ -regexp\ able\ to\ use\ ()\ match\ variables?\ I\ think\ perl\ store\ the\ regexp\ matches\ in\ global\ variables\ \$1\ ..\ \$9\ \n\nswitch\ -regexp\ --\ \$somevar\ \{\n\ switch\ -regexp\ --\ \$somevar\ \{\n\ \ \ \ \{^(\\d+)\\s+(\\d+)\}\ \{puts\ \"You\ hit\ number\ matches\ \$1\ and\ \$2\"\}\n\}\n\ \}\n\n\[KBK\]\ -\ You\ can't.\ \ However,\ that\ form\ of\ \[\[switch\]\]\ is\ no\ slower\ than\ the\ corresponding\ \[\[if\]\]...\[\[elseif\]\],\ \n\nif\ \{\[regexp\ \{^(\\S+)\\s+(\\S+)\$\}\ \$somevar\ ->\ part1\ part2\]\}\ \{\n\ \ \ if\ \{\ \[regexp\ \{^(\\S+)\\s+(\\S+)\$\}\ \$somevar\ ->\ part1\ part2\]\ \}\ \{\n\ \ \ \ \ \ \ \ puts\ \"You\ hit\ matches\ \$part1\ and\ \$part2\"\n\ \ \ \ \}\ elseif\ \{\ \[regexp\ \{^(\\d+)\\s+(\\d+)\}\ ->\ part1\ part2\]\ \}\ \{\n\ \ \ \ \ \ \ \ puts\ \"You\ hit\ number\ matches\ \$part1\ and\ \$part2\"\n\ \ \ \ \}\n\n\[hkoba\],\ 2005-03-18:\ Hmm,\ how\ about\ \[switch-regexp\]?\n\[hkoba\]\ 2005-03-18:\ Hmm,\ how\ about\ \[switch-regexp\]?\n\n----\nHow's\ this\ for\ a\ silly\ compromise.\ \nNicely\ aligns\ the\ dispatch\ conditions\ and\ removes\ the\ confusing\ barrage\ of\ backslashes.\n======\n\ if\ \{0\}\ \{\n\ \}\ elseif\ \{\$state\ ==\ \$INIT_STATE\}\ \{\n\n\ \ \ \ puts\ init\n\n\ \}\ elseif\ \{\$state\ ==\ \$CLEANING_STATE\}\ \{\n**\ Delimiting\ the\ Options\ **\n\ \ \ \ puts\ cleaning\n\[LES\]:\ So,\ if\ it\ is\ so\ good\ a\ practice\ ALWAYS\ to\ call\ switch\ as\ \"switch\ --\"\ (the\ switch\ to\ end\ all\ switches),\ why\ can't\ the\ core\ code\ already\ cope\ with\ that?\n\ \}\ elseif\ \{\$state\ ==\ \$DONE_STATE\}\ \{\n\n\ \ \ \ puts\ done\n\n\ \}\n======\n----\nThe\ silliness\ continues...\ this\ actually\ works\ though\ I'm\ not\ sure\ of\ the\ side\ effects.\n======\n\ proc\ dispatch\ \{thevar\ args\}\ \{\n\ \ \ \ \ set\ pass1\ \[uplevel\ subst\ \$args\]\n\ \ \ \ \ set\ pass2\ \"switch\ \\\$\$thevar\ \\\{\ \$pass1\ \\\}\"\n\ \ \ \ \ uplevel\ \$pass2\n\ \}\n\ \n\ set\ INIT_STATE\ \"init\"\n\ set\ CLEANING_STATE\ \"cleaning\"\n\ set\ DONE_STATE\ \"done\"\n\ \n\ set\ state\ \$INIT_STATE\n\ \n\ dispatch\ state\ \{\n\ \ \ \ \ \$INIT_STATE\ \{\n\ \n\ \ \ \ \ \ \ \ \ puts\ init\n\ \ \ \ \ \ \ \ \ set\ nextstate\ \$DONE_STATE\n\ \n\ \ \ \ \ \}\n\ \ \ \ \ \$CLEANING_STATE\ \{\n\ \n\ \ \ \ \ \ \ \ \ puts\ cleaning\n\ \n\ \ \ \ \ \}\n\ \ \ \ \ \$DONE_STATE\ \{\n\ \n\ \ \ \ \ \ \ \ \ puts\ done\n\ \n\ \ \ \ \ \}\n\ \ \ \ \ default\ \{\n\ \ \ \ \ \}\n\ \}\n\ puts\ \"next\ state\ \$nextstate\"\n======\n----\nSee\ also\ \[ranged\ switch\]\n\n----\n\n\[MG\]:\ That's\ not\ really\ specific\ to\ switch\ -\ it's\ really\ good\ practice\ with\ ''all''\ commands\ that\ take\ ''-something''\ args,\ and\ show\ the\ end\ of\ those\ with\ '--',\ to\ include\ the\ --.\ And\ I\ think\ the\ reason\ the\ core\ can't\ handle\ is\ that\ sometimes\ you\ may\ actually\ want\ the\ behaviour\ that\ occurs\ when\ you\ don't\ give\ `--`.\n\[MG\]\ That's\ not\ really\ specific\ to\ switch\ -\ it's\ really\ good\ practice\ with\ ''all''\ commands\ that\ take\ ''-something''\ args,\ and\ show\ the\ end\ of\ those\ with\ '--',\ to\ include\ the\ --.\ And\ I\ think\ the\ reason\ the\ core\ can't\ handle\ is\ that\ you\ may\ actually\ want\ the\ behaviour\ that\ occurs\ when\ you\ don't\ give\ --,\ some\ times.\ \n\[LV\]:\ because\ technically\ the\ rule\ isn't\ \"ALWAYS\ call\ switch\ as\ `switch\ --`\".\n\[LV\]\ because\ technically\ the\ rule\ isn't\ \"ALWAYS\ call\ switch\ as\ `switch\ --`\".\nThe\ rule\ is\ \"ALWAYS\ call\ switch\ with\ --\ after\ the\ last\ of\ the\ switch\nThink\ of\ code\ like\ this:\n\nset\ arg\ \{something\ entered\ by\ the\ user\}\n\ set\ arg\ \"something\ entered\ by\ the\ user\"\n\ switch\ \$arg\ \{\n\ \ \ \ \ \ \ \ --first_thing\ \{\ do\ something\ \}\n\ \ \ \ \ \ \ \ --second_thing\ \{\ do\ something\ else\ \}\n\ \ \ \ \ \ \ \ default\ \{do\ the\ last\ thing\ \}\n\ \}\n\nNow,\ if\ the\ user\ happens\ to\ type\ in\ \"--first_thing\",\ the\ program\n\n\ bad\ option\ \"--first_thing\":\ must\ be\ -exact,\ -glob,\ -regexp,\ or\ --\nbecause\ there\ was\ no\ \"--\"\ between\ the\ switch\ and\ the\ variable\ being\nexamined.\ Not\ only\ that,\ but\ if\ the\ user\ happens\ to\ type\ in\ \"-exact\",\n\n\ wrong\ #\ args:\ should\ be\ \"switch\ ?switches?\ string\ pattern\ body\ ...\ ?default\ body?\"\nbecause\ of\ the\ missing\ \"--\"\ .\ \ Two\ potential\ error\ situations\ -\ and\ncalled,\ any\ information\ about\ where\ the\ first\ argument\ is\ already\ gone.\n\n\[RS\]:\ The\ need\ for\ `--`\ seems\ to\ exist\ only\ for\ ''switch''.\ Other\ commands\ don't\ get\ confused\ by\ parameters\ that\ look\ like\ switches\ but\ aren't:\n\[RS\]\ The\ need\ for\ --\ seems\ to\ exist\ only\ for\ ''switch''.\ Other\ commands\ don't\ get\ confused\ by\ parameters\ that\ look\ like\ switches\ but\ aren't:\n\ %\ lsearch\ -foo\ -bar\n\ -1\nThen\ again,\ \[regexp\]\ has\ the\ same\ need\ for\ --:\n\ %\ regexp\ -foo\ -bar\n\ bad\ switch\ \"-foo\":\ must\ be\ -all,\ -about,\ -indices,\ -inline,\ -expanded,\ -line,\ -linestop,\ -lineanchor,\ -nocase,\ -start,\ or\ --\n======none\nYax:\ lsearch\ assumes\ the\ form\ of\ arguments\ by\ the\ argument\ count,\ and\ its\ quite\ probable\ that\ all\ commands\ that\ take\ fixed\ args\ after\ options\ do.\ Any\ commands\ (such\ as\ regexp)\ that\ can\ take\ an\ arbitrarily\ varying\ number\ of\ args\ and\ have\ switches\ probably\ also\ suffer\ this\ issue.\nThen\ again,\ `\[regexp\]`\ has\ the\ same\ need\ for\ `--`:\n----\n\[RS\]\ 2005-05-30:\ Unlike\ in\ \[C\],\ \[Tcl\]'s\ \[switch\]\ returns\ its\ last\ evaluated\ result,\ \nso\ it\ can\ be\ used\ as\ a\ function.\ Given\ this\ simple\ identity\n\n\ proc\ is\ x\ \{set\ x\}\n\n\nforeach\ num\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\ 7\ 8\ 9\}\ \{\n\ foreach\ num\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\ 7\ 8\ 9\}\ \{\n\ \ \ \ \ \ \ \ 1\ -\ 9\ \ \ \ \ \ \ \ \ \{is\ odd\}\n\ \ \ \ \ \ 1\ -\ 9\ \ \ \ \ \ \ \ \ \{is\ odd\}\n\ \ \ \ \ \ 2\ -\ 3\ -\ 5\ -\ 7\ \{is\ prime\}\n\ \ \ \ \ \ 0\ -\ 4\ -\ 6\ -\ 8\ \{is\ even\}\n\ \ \ \ puts\ \"\$num\ is\ \$type\"\n\}\n\ \}\n\n\n\ 0\ is\ even\n\ 1\ is\ odd\n\ 2\ is\ prime\n\ 3\ is\ prime\n\ 4\ is\ even\n\ 5\ is\ prime\n\ 6\ is\ even\n\ 7\ is\ prime\n\ 8\ is\ even\n\ 9\ is\ odd\n======none\n\[ZB\]\ 20100318\ -\ the\ above\ example\ doesn't\ work\ (invalid\ command\ name\ \"is\").\ I've\ got\ a\ feeling,\ it\ was\ probably\ valid\ for\ TCL8.4\ (didn't\ check\ it),\ but\ it\ won't\ work\ with\ 8.6\ anymore.\n\n\[Lars\ H\]:\ More\ likely,\ you\ forgot\ to\ include\ the\ definition\ of\ '''is'''\ (the\ proc\ command\ in\ the\ preceeding\ one-line\ code\ block).\n\n\[ZB\]\ Oh,\ yeah...\ O_O\ indeed.\n\n\[AMG\]:\ See\ \[return\]\ for\ more\ discussion\ of\ this\ pattern.\ \ Search\ for\ \"return\ -level\ 0\".\ \ I\ have\ found\ that\ the\ simplest\ way\ to\ do\ it\ is\ with\ single-argument\ \[lindex\].\ \ Elsewhere\ I've\ seen\ it\ done\ with\ single-argument\ \[list\],\ but\ this\ is\ unsafe.\n\n----\n\[LV\]\ Can\ someone\ help\ me\ with\ switch?\ I\ have\ what\ seems\ like\ a\ simple\nbit\ of\ code,\ but\ it\ doesn't\ work\ as\ I\ expected.\ So\ I\ need\ help\ adjusting\nmy\ expectation\ (and\ my\ code!).\n\n\ \$\ cat\ ts.tcl\n\ #!\ /usr/tcl84/bin/tclsh\n\[AMG\]:\ See\ \[identity\ function\ \]\ for\ more\ discussion\ of\ this\ pattern.\ \ The\ simplest\ way\ to\ do\ it\ is\ with\n\ set\ ::expert\ \"no\"\n\ set\ ::usage\ \"USAGE:\ \$argv0\ arg1\ arg2\"\n\ set\ ::val\ \"XYZ\"\n\n\ foreach\ i\ \$::argv\ \{\ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ switch\ -exact\ --\ \$i\ in\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ !\ \ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$::expert\ ==\ \"no\"\}\ \{\ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ ::expert\ \"yes\"\ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \$::usage\ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ exit\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n**\ History\ **\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 1\ \{\ set\ \$::val\ 1\ \}\nFirst\ announced\ by\ \[JO\]\ for\ Tcl\ 7.0\ in\ \[https://groups.google.com/d/msg/comp.lang.tcl/u1pATk0ytWM/8uStOsyBrLYJ%|%Advice\ wanted:\ \"case\"\ command\ and\ regexps\],\ \[comp.lang.tcl\],1993-06-05\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ default\ \{\ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"**\ Too\ many\ values\ specified\ **\"\ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"You\ will\ be\ prompted\ for\ the\ information\ **\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ ::expert\ \"no\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ \n\ \}\n\n\ puts\ \$::expert\n\ puts\ \$::val\n\ \$\ ts.tcl\ 1\ 2\ !\n\ no\n\ XYZ\n======\nI\ was\ expecting\ to\ see\ \n\n\ no\ \n\ **\ Too\ many\ values\ specified\ **\n\ You\ will\ be\ prompted\ for\ the\ information\ **\n\ 1\n**\ Compilation\ Notes\ **\nas\ a\ result,\ since\ I\ supplied\ a\ 2\ and\ a\ !.\n\[DKF\]:\ In\ Tcl\ \[Changes\ in\ Tcl/Tk\ 8.5%|%8.5\],\ `switch`\ is\ \[bytecode%|%byte-compiled\]\ if\ reasonably\ possible.\ The\ \"reasonably\ possible\"\ part\ means\ that\ you\ do\ have\ to\ be\ doing\ either\ '''`-exact`'''\ or\ '''`-glob`'''\ matching,\ and\ the\ bodies\ of\ the\ arms\ have\ to\ be\ compilable\ (as\ usual).\ With\ '''`-regexp`'''\ matching,\ that\ always\ goes\ to\ the\ \"interpreted\"\ version\ (though\ by\ compensation,\ there\ are\ some\ other\ new\ goodies\ (see\ `-matchvar`\ and\ `-indexvar`,\ for\ instance)\ available).\nWhat\ am\ I\ missing\ in\ this?\nIn\ most\ cases,\ the\ switch\ is\ compiled\ to\ (effectively)\ a\ sequence\ of\ `\[if\]`\ commands.\ However,\ in\ some\ special\ cases,\ i.e.\ '''`-exact`'''\ matching\ of\ constant\ terms,\ a\ jump\ table\ is\ built\ instead,\ which\ is\ considerably\ more\ efficient,\ especially\ for\ terms\ other\ than\ the\ first\ one.\n\[RHS\]\ You\ have\ an\ '''in'''\ there\ that\ you\ shouldn't:\n\ switch\ -exact\ --\ \$i\ in\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ^^\n\n----\n'''Compilation\ Notes'''\n**\ Bug:\ `-indexvar`\ Indexes\ Off\ By\ One\ **\n\[DKF\]:\ In\ Tcl\ 8.5,\ the\ '''switch'''\ command\ is\ bytecompiled\ if\ reasonably\ possible.\ The\ \"reasonably\ possible\"\ part\ means\ that\ you\ do\ have\ to\ be\ doing\ either\ '''-exact'''\ or\ '''-glob'''\ matching,\ and\ the\ bodies\ of\ the\ arms\ have\ to\ be\ compilable\ (as\ usual).\ With\ '''-regexp'''\ matching,\ that\ always\ goes\ to\ the\ \"interpreted\"\ version\ (though\ by\ compensation,\ there\ are\ some\ other\ new\ goodies\ (see\ -matchvar\ and\ -indexvar,\ for\ instance)\ available).\n\[TJE\]:\ Why\ are\ the\ ranges\ placed\ in\ a\ `switch`\ statement's\ `-indexvar`\ target\ inclusive\ of\ the\ character\ AFTER\ the\ match?\ \ This\ differs\ from\ the\ behavior\ of\ regexp's\ `-indices`\ option,\ which\ seems\ quite\ odd\ to\ me.\ \ For\ example:\nIn\ most\ cases,\ the\ switch\ is\ compiled\ to\ (effectively)\ a\ sequence\ of\ \[if\]s.\ However,\ in\ some\ special\ cases\ (i.e.\ '''-exact'''\ matching\ of\ constant\ terms)\ a\ jump\ table\ is\ built\ instead,\ which\ is\ considerably\ more\ efficient,\ especially\ for\ terms\ other\ than\ the\ first\ one.\n======\n----\n\[TJE\]\ Why\ are\ the\ ranges\ placed\ in\ a\ switch\ statement's\ \"-indexvar\"\ target\ inclusive\ of\ the\ character\ AFTER\ the\ match?\ \ This\ differs\ from\ the\ behavior\ of\ regexp's\ \"-indices\"\ option,\ which\ seems\ quite\ odd\ to\ me.\ \ For\ example:\n%\ set\ line\ \{foo\ bar\}\n\ \ %\ set\ line\ \{foo\ bar\}\n\ \ foo\ bar\n\ \ %\ regexp\ -inline\ -indices\ \{foo\}\ \$line\n\ \ \{0\ 2\}\n\ \ %\ switch\ -regexp\ -indexvar\ index\ --\ \$line\ \{foo\}\ \{set\ index\}\n\ \ \{0\ 3\}\n\n\n\[PYK\]\ 2014-05-30:\ If\ this\ really\ happened,\ it\ must\ have\ been\ a\ bug\ in\ some\n\n\[\[Anyone\ have\ an\ example\ of\ a\ switch\ statement\ with\ two\ or\ more\ cases,\ with\ comments\ for\ each\ case?\]\]\n\[Wookie\]:\ I\ have\ a\ large\ switch\ and\ wanted\ comments\ for\ blocks\ of\ statements\ e.g.\nThe\ man\ page\ \[http://www.tcl.tk/man/tcl8.5/TclCmd/switch.htm\]\ includes\ such\ an\ example.\n\n\nswitch\ -exact\ --\ \$test\ \{\n\ \ switch\ -exact\ --\ \$test\ \{\n\ \ \ \ Test1\ \{do\ stuff...\}\n\ \ \ \ Test1\ \{\ SomeProcs...\}\n\ \ \ \ Test2\ \{\ SomeProcs...\}\n\n\ \ \ \ Test3\ \{do\ stuff...\}\n\ \ \ \ Test3\ \{\ SomeProcs...\}\n\ \ \ \ Test4\ \{\ SomeProcs...\}\n\n\ \ \ \ NONE\ -\n\ \ \ \ default\ \{SomeCleanUpProc...\}\n\ \ \ \ default\ \{\ SomeCleanUpProc...\ \}\n\ \ \}\n\n\ \ \ \"extra\ switch\ pattern\ with\ no\ body,\ this\ may\ be\ due\ to\ a\ comment\ incorrectly\ placed\ outside\ of\ a\ switch\ body\ -\ see\ the\ \"switch\"\ documentation\"\n\nAs\ Tcl\ `switch`\ statements\ don't\ seem\ to\ care\ that\ there\ are\ multiple\ definitions\ of\ a\ statement,\ I\ rewrote\ the\ code\ as:\ \nAs\ TCL\ switch\ statements\ don't\ seem\ to\ care\ that\ there\ are\ multiple\ definitions\ of\ a\ statement,\ I\ rewrote\ the\ code\ as:\ \nswitch\ -exact\ --\ \$test\ \{\n\ \ switch\ -exact\ --\ \$test\ \{\n\ \ \ \ Test1\ \{do\ stuff...\}\n\ \ \ \ Test1\ \{\ SomeProc...\}\n\ \ \ \ Test2\ \{\ SomeProc...\}\n\n\ \ \ \ Test3\ \{do\ stuff...\}\n\ \ \ \ Test3\ \{\ SomeProc...\}\n\ \ \ \ Test4\ \{\ SomeProc...\}\n\n\ \ \ \ NONE\ -\n\ \ \ \ default\ \{clean\ up\ stuff...\}\n\ \ \ \ default\ \{\ SomeCleanUpProc...\ \}\n\ \ \}\ \n\n\n----\n\[DrASK\]\ -\ Is\ there\ any\ speed\ improvement\ when\ using\ -exact\ over\ -regexp?\ As\ in:\nset\ number\ 0x5\n\ \ \ switch\ -exact\ --\ \$value\ \{\n\ \ \ \ \ \ \{a\}\ -\ \{b\}\ -\ \{c\}\ \{match\}\n\ \ \ \}\nYou\ may\ instead\ consider\ a\ long\ `\[if\]`/`\[elseif\]`\ chain,\ but\ maybe\ this\ won't\ \[bytecode\]\ as\ well.\ \ Alternately,\ force\ the\ \[format%|%formatting\]\ to\ be\ consistent:\n\ \ \ switch\ -regexp\ --\ \$value\ \{\n\ \ \ \ \ \ \{\[abc\]\}\ \{match\}\n\ \ \ \}\nset\ number\ 0x5\n\[Lars\ H\]:\ Comments\ by\ '''DKF'''\ above\ suggest\ that\ the\ answer\ should\ be\ yes,\ but\ why\ not\ check\ for\ yourself?\ \[time\]\ it!\n\n\nswitch\ -regexp\ --\ \$value\ \{\n\ \ \ switch\ -regexp\ --\ \$value\ \{\n\ \ \ \ \ \ \{^\[abc\]\$\}\ \{match\}\n\ \ \ \}\n\n\[DrASK\]\ Yeah,\ I\ failed\ to\ mention\ that\ \$value\ is\ known\ to\ be\ a\ single\ character.\ Thanks.\ Here\ is\ the\ test\ and\ the\ results:\nproc\ exact\ value\ \{\n\ proc\ exact\ \{value\}\ \{\n\ \ \ \ \ \ \ \ a\ -\ b\ -\ c\ \{return\ true\}\n\ \ \ \ \ \ \ \ default\ \{return\ false\}\n\ \ \ \ \}\n\}\n\ \}\nproc\ re\ value\ \{\n\ proc\ regexp\ \{value\}\ \{\n\ \ \ \ \ \ \ \ \[abc\]\ \{return\ true\}\n\ \ \ \ \ \ \ \ \{\[abc\]\}\ \{return\ true\}\n\ \ \ \ \}\n\}\n\ \}\nproc\ first\ value\ \{\n\ proc\ first\ \{value\}\ \{\n\ \ \ \ return\ \[expr\ \{\[string\ match\ \$value\ \{abc\}\]\ !=\ -1\}\]\n\ \}\nproc\ multi\ \{type\ value\}\ \{\n\ proc\ multi\ \{type\ value\}\ \{\n\ \ \ \ \ \ \ \ \$type\ \$value\n\ \ \ \ \}\n\}\n\ \}\nforeach\ type\ \{exact\ re\ first\}\ \{\n\ foreach\ type\ \{exact\ regexp\ first\}\ \{\n\ \ \ \ \ \ \ \ puts\ \"\$type\ \$value\ \[errortime\ \{multi\ \$type\ \$value\}\ 10000\ 100\]\"\n\ \ \ \ \}\n\}\n\ \}\n\ \n\ exact\ a\ 66\ +/-\ 0\ microseconds\ per\ iteration\n\ exact\ b\ 67\ +/-\ 0\ microseconds\ per\ iteration\n\ exact\ c\ 67\ +/-\ 0\ microseconds\ per\ iteration\n\ exact\ d\ 66\ +/-\ 0\ microseconds\ per\ iteration\n\ regexp\ a\ 151\ +/-\ 0\ microseconds\ per\ iteration\n\ regexp\ b\ 140\ +/-\ 0\ microseconds\ per\ iteration\n\ regexp\ c\ 142\ +/-\ 0\ microseconds\ per\ iteration\n\ regexp\ d\ 121\ +/-\ 0\ microseconds\ per\ iteration\n\ first\ a\ 71\ +/-\ 0\ microseconds\ per\ iteration\n\ first\ b\ 71\ +/-\ 0\ microseconds\ per\ iteration\n\ first\ c\ 71\ +/-\ 0\ microseconds\ per\ iteration\n\ first\ d\ 70\ +/-\ 0\ microseconds\ per\ iteration\n======none\nIt's\ interesting\ to\ note\ the\ dropoff\ when\ regexp\ hit\ the\ default\ case.\ But\ -regexp\ is\ clearly\ is\ 2-2.5x\ slower.\ I\ used\ \[MAK\]'s\ errortime\ proc\ \[http://wiki.tcl.tk/924\]\ for\ timing.\nIt's\ interesting\ to\ note\ the\ dropoff\ when\ `\[regexp\]`\ hit\ the\ default\ case.\ But\ `-regexp`\ is\ clearly\ is\ 2-2.5x\ slower.\ I\ used\ \[MAK\]'s\ \[How\ to\ Measure\ Performance%|%errortime\ proc\]\ for\ timing.\n\[ferrieux\]:\ Indeed,\ timing\ shows\ that\ the\ jump\ table\ is\ roughly\ 3x\ faster\ than\ if..elseif..elseif,\ which\ is\ itself\ 1.25x\ faster\ than\ regexp.\ Notice\ that\ the\ regexp\ compilation\ overhead\ is\ not\ in\ the\ picture,\ since\ it\ is\ cached.\ Not\ sure\ whether\ we\ should\ worry\ about\ the\ 1.25...\n\[ferrieux\]:\ Indeed,\ timing\ shows\ that\ the\ jump\ table\ is\ roughly\ 3x\ faster\ than\ `if..elseif..elseif`,\ which\ is\ itself\ 1.25x\ faster\ than\ `\[regexp\]`.\ Notice\ that\ the\ `\[regexp\]`\ compilation\ overhead\ is\ not\ in\ the\ picture,\ since\ it\ is\ cached.\ Not\ sure\ whether\ we\ should\ worry\ about\ the\ 1.25...\n----\n\[AMG\]:\ Unlike\ \[C\]\ switch\ which\ does\ numeric\ comparisons,\ \[Tcl\]\ switch\ performs\ string\ comparisons.\ \ This\ can\ make\ a\ big\ difference\ in\ your\ program\ if\ you\ are\ dealing\ with\ numbers\ that\ are\ formatted\ in\ different\ ways.\n\n======\nset\ number\ 0x5\nswitch\ --\ \$number\ \{\n5\ \ \ \ \ \ \ \{puts\ five!\}\ndefault\ \{puts\ unknown\}\n\}\n======\n**\ An\ Implementation\ in\ Tcl\ **\nYou\ may\ instead\ consider\ a\ long\ \[if\]/\[elseif\]\ chain,\ but\ maybe\ this\ won't\ \[bytecode\]\ as\ well.\ \ Alternately,\ force\ the\ \[format\]ting\ to\ be\ consistent:\n\[rwm\]:\ I\ recently\ needed\ to\ run\ some\ \[Changes\ in\ Tcl/Tk\ 8.5%|%8.5\]\ code\ in\ \[Changes\ in\ Tcl/Tk\ 8.4%|%8.4\].\ \ I\ wrote\ the\ following\ code\ to\ mimic\ the\ 8.5\ switch\ in\ 8.4.\ (I\ looked\ for\ but\ could\ not\ find\ a\ compatibility\ library...)\ Note\ the\ many\ errors\ for\ cases\ that\ I\ did\ not\ need.\ \ Maybe\ someone\ else\ will\ cover\ fix/post\ those\ \;)\ \ Feel\ free\ to\ edit/move\ this\ as\ appropriate.\n======\nset\ number\ 0x5\nswitch\ --\ \[format\ %d\ \$number\]\ \{\n5\ \ \ \ \ \ \ \{puts\ five!\}\ndefault\ \{puts\ unknown\}\n\}\n======\n======\n----\n\[rwm\]:\ I\ recently\ needed\ to\ run\ some\ 8.5\ code\ in\ 8.4.\ \ I\ wrote\ the\ following\ code\ to\ mimic\ the\ 8.5\ switch\ in\ 8.4.\ (I\ looked\ for\ but\ could\ not\ find\ a\ compatibility\ library...)\ Note\ the\ many\ errors\ for\ cases\ that\ I\ did\ not\ need.\ \ Maybe\ someone\ else\ will\ cover\ fix/post\ those\ \;)\ \ Feel\ free\ to\ edit/move\ this\ as\ appropriate.\n\nproc\ switch_8.5\ args\}\ \{\nproc\ switch_8.5\ \{args\}\ \{\n\ \ \ ##\ this\ is\ an\ 8.4\ version\ of\ the\ 8.5\ switch\ (incomplete)\n\ \ \ if\ \{\[llength\ \$args\]\ <\ 2\}\ \{\n\ \ \ \ \ \ error\ \"usage:\ switch\ ?options?\ string\ \{pattern\ body\ ?pattern\ body\ ...?\}\"\n\ \ \ \}\n\ \ \ set\ type\ exact\n\ \ \ while\ \{\[string\ match\ \"-*\"\ \[lindex\ \$args\ 0\]\]\}\ \{\n\ \ \ \ \ \ set\ option\ \[lindex\ \$args\ 0\]\n\ \ \ \ \ \ set\ args\ \[lrange\ \$args\ 1\ end\]\n\ \ \ \ \ \ switch\ --\ \$option\ \{\n\ \ \ \ \ \ \ \ \ -exact\ \ \ \ \{set\ type\ exact\}\n\ \ \ \ \ \ \ \ \ -nocase\ \ \ \{set\ type\ nocase\}\n\ \ \ \ \ \ \ \ \ -glob\ \ \ \ \ \{set\ type\ glob\}\n\ \ \ \ \ \ \ \ \ -regexp\ \ \ \{set\ type\ regexp\}\n\ \ \ \ \ \ \ \ \ -matchvar\ \{set\ matchvar\ \[lindex\ \$args\ 0\]\;\ set\ args\ \[lrange\ \$args\ 1\ end\]\}\n\ \ \ \ \ \ \ \ \ -indexvar\ \{error\ \"unimplemented\"\}\n\ \ \ \ \ \ \ \ \ --\ \{break\}\n\ \ \ \ \ \ \ \ \ default\ \{error\ \"bad\ switch\ option=\$option\"\}\n\ \ \ \ \ \ \}\n\ \ \ \}\n\ \ \ set\ string\ \[lindex\ \$args\ 0\]\n\ \ \ if\ \{\[llength\ \$args\]\ ==\ 2\}\ \{\n\ \ \ \ \ \ set\ body\ \[lindex\ \$args\ 1\]\n\ \ \ \}\ else\ \{\ \n\ \ \ \ \ \ set\ body\ \[lrange\ \$args\ 1\ end\]\n\ \ \ \}\n\ \ \ switch\ --\ \$type\ \{\n\ \ \ \ \ \ exact\ \ \{error\ \"unimplemented\"\}\n\ \ \ \ \ \ nocase\ \{error\ \"unimplemented\"\}\n\ \ \ \ \ \ glob\ \ \ \{error\ \"unimplemented\"\}\n\ \ \ \ \ \ regexp\ \{\n\ \ \ \ \ \ \ \ \ foreach\ \{rexp\ script\}\ \$body\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\ \$rexp\ ==\ \"default\"\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ uplevel\ 1\ \$script\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[regexp\ --\ \$rexp\ \$string\ match\ 1\ 2\ 3\ 4\ 5\ 6\ 7\ 8\ 9\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[info\ exists\ matchvar\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ upvar\ \$matchvar\ m\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ m\ \[list\ \$match\ \$1\ \$2\ \$3\ \$4\ \$5\ \$6\ \$7\ \$8\ \$9\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ uplevel\ 1\ \$script\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ unset\ m\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ uplevel\ 1\ \$script\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ break\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \}\n\ \ \ \ \ \ default\ \{error\ \"internal\ type=\$type\ error\"\}\n\ \ \ \}\n======\n\n----\n\[neb\]\ ddd\ asked\ about\ http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/b6c3591dbbbf2b40?hl=en%|%extending\ switch\ statements%|%.\ I'm\ putting\ some\ of\ the\ answers\ here,\ because\ I\ intend\ to\ possibly\ use\ them\ =\]\n\nSchelte\ Bron\ said:\ The\ switch\ command\ (at\ least\ in\ the\ format\ you\ used)\ takes\ a\ list\ as\ its\ last\ argument.\ So\ you\ can\ simply\ put\ that\ into\ a\ variable\ and\ use\ the\ normal\ list\ operations\ to\ manipulate\ it:\nset\ switch\ \{\n\ \ \ a*b\ \ \ \ \ -\n\ \ \ b\ \ \ \ \ \ \ \{expr\ 1\}\n\ \ \ b\ \ \ \ \ \ \ \{expr\ \{1\}\}\n\ \ \ a*\ \ \ \ \ \ \{expr\ \{2\}\}\n\ \ \ default\ \{expr\ \{3\}\}\n\nswitch\ -glob\ aaab\ \$switch\n\nset\ switch\ \[linsert\ \$switch\ end-2\ c\ \{expr\ 4\}\]\nset\ switch\ \[linsert\ \$switch\ end-2\ c\ \{expr\ \{4\}\}\]\nswitch\ -glob\ c\ \$switch\n======\n\ndkf\ said:\ I'd\ do\ it\ like\ this,\ using\ the\ alternate\ form\ of\ \[switch\]:\nset\ defs\ \{\n\ \ set\ defs\ \{\n\ \ \ \ \ \ a*b\ \ \ \ \ -\n\ \ \ \ \ \ b\ \ \ \ \ \ \ \{expr\ \{1\}\}\n\ \ \ \ \ \ a*\ \ \ \ \ \ \{expr\ \{2\}\}\n\ \ \}\nswitch\ -glob\ --\ \$value\ \{*\}\$defs\ default\ \{\n\ \ switch\ -glob\ --\ \$value\ \{*\}\$defs\ default\ \{\n\ \ \ \ \ \ expr\ \{3\}\n\ \ \}\n\n\nlappend\ defs\ c\ \{expr\ 4\}\n\ \ lappend\ defs\ c\ \{expr\ \{4\}\}\n\nYet\ you\ won't\ disrupt\ the\ special\ handling\ of\ 'default',\ which\ has\ to\ be\ the\ last\ clause.\ (You\ could\ also\ put\ the\ default\ handling\ script\ in\ its\ own\ variable,\ or\ other\ arbitrarily\ complex\ solution.\ Your\ call.)\ \nYet\ you\ won't\ disrupt\ the\ special\ handling\ of\ `default`,\ which\ has\ to\ be\ the\ last\ clause.\ (You\ could\ also\ put\ the\ default\ handling\ script\ in\ its\ own\ variable,\ or\ other\ arbitrarily\ complex\ solution.\ Your\ call.)\ \n<<discussion>>\n----\n!!!!!!\n%|\ \[Category\ Command\]\ |\ \[Category\ Control\ Structure\]\ |%\n\[Tcl\ syntax\ help\]\ |\ \[Arts\ and\ crafts\ of\ Tcl-Tk\ programming\]\n!!!!!!} CALL {my revision switch} CALL {::oo::Obj4278317 process revision/switch} CALL {::oo::Obj4278315 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