control(3tcl)
π control β Procedures for control flow structures π
okay bestie, so this is control(3tcl), aka the Tcl Control Flow Commands page from tcllib. it's all about making Tcl do the lil flow-control tricks other languages get for free. no cap, it's giving "keywords but make them just commands". let's get into it π¦
β¨ SYNOPSIS β¨
package require Tcl 8.5 9
package require control ?0.1.4?
control::control command option ?arg arg ...?
control::assert expr ?arg arg ...?
control::do body ?option test?
control::no-op ?arg arg ...?
πΈ DESCRIPTION πΈ
so the control package hands you a whole lil collection of commands that give you extra flow-of-control structures on top of the ones Tcl already ships with. these are the kinds of things that in a lot of programming languages would just be keywords, like, baked right into the language itself. but in Tcl? control flow structures are just commands like everything else. iconic behavior honestly π
π COMMANDS π
π control::control β the config queen
control::control command option ?arg arg ...?
control::control is the configuration command for customizing all the other public commands in the control package. the command argument names whichever command you wanna customize. the valid options and whatever args come after them depend entirely on the command you're customizing, and they're documented with that command. so like, iykyk β go read the specific command's section π₯
π control::assert β the vibe checker
control::assert expr ?arg arg ...?
when it's disabled, assert behaves exactly like the no-op command. like, literally identical energy.
when it's enabled, assert evaluates expr as an expression (same way expr evaluates its argument). now listen:
- if evaluating shows that
expris not a valid boolean expression (per[string is boolean -strict]), an error is raised. oop π - if
exprevaluates to a true boolean value (as recognized byif), thenassertreturns an empty string. slay, everything's fine. - otherwise β bestie, we got a problem β the remaining arguments to
assertget used to build a message string:- if there are no arguments, the message string is
"assertion failed: $expr". - if there are arguments, they get joined by
jointo form the message string. - then that message string is appended as an argument to a callback command, and the completed callback command is evaluated in the global namespace.
- if there are no arguments, the message string is
the assert command can be customized by the control command in two ways, bestie, pay attention π
[control::control assert enabled ?boolean?]β queries or sets whethercontrol::assertis enabled. call it with nobooleanargument and you get back a boolean value saying whethercontrol::assertis enabled. call it with a valid boolean value as thebooleanargument and thecontrol::assertcommand gets enabled or disabled to match, and an empty string comes back.[control::control assert callback ?command?]β queries or sets the callback command that an enabledassertwill call on assertion failure. call it with nocommandargument and you get the current callback command. call it with acommandargument and that argument becomes the new assertion failure callback command. note: an assertion failure callback command is always defined, even whenassertis disabled. the default callback command is[return -code error].
and here's the cute part: control::assert was written so that, in combination with [namespace import], you can have enabled assert commands in some namespaces and disabled assert commands in other namespaces at the same time. that's lowkey super useful because it means debugging efforts can be controlled independently, module by module. main character energy fr fr β¨
% package require control
% control::control assert enabled 1
% namespace eval one namespace import ::control::assert
% control::control assert enabled 0
% namespace eval two namespace import ::control::assert
% one::assert {1 == 0}
assertion failed: 1 == 0
% two::assert {1 == 0}
π control::do β the looper
control::do body ?option test?
do evaluates the script body over and over until the expression test becomes true, or for as long as (while) test is true β depending on whether option is until or while.
if option and test are omitted, the body is evaluated exactly once. after normal completion, do returns an empty string.
exceptional return codes (break, continue, error, etc.) that happen during evaluation of body get handled the same way the while command handles them β except as noted in LIMITATIONS, down below π
π control::no-op β the do-nothing icon
control::no-op ?arg arg ...?
no-op takes any number of arguments and does absolutely nothing with them. it returns an empty string. that's it, that's the whole command. honestly? relatable. π
π LIMITATIONS π
so several of the commands the control package gives you accept arguments that are scripts to be evaluated. and because of fundamental limitations of Tcl's catch and return commands, it is not possible for these commands to properly evaluate the command [return -code $code] inside one of those script arguments, for any value of $code other than ok.
which means the commands of the control package are limited compared to Tcl's built-in control flow commands (like if, while, etc.) and compared to control flow commands that can be provided by packages coded in C. here's what that difference actually looks like:
% package require control
% proc a {} {while 1 {return -code error a}}
% proc b {} {control::do {return -code error b} while 1}
% catch a
1
% catch b
0
see? not the same. no cap. π«Ά
π BUGS, IDEAS, FEEDBACK π
this document, and the package it describes, will undoubtedly contain bugs and other problems. (they said it, not me!) please report such in the category control of the Tcllib Trackers at http://core.tcl.tk/tcllib/reportlist. also please report any ideas for enhancements you may have for either the package and/or the documentation. we wanna hear it π
when proposing code changes, please provide unified diffs, i.e. the output of diff -u.
note further that attachments are strongly preferred over inlined patches. attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar. π
π SEE ALSO π
break, continue, expr, if, join, namespace, return, string, while
β KEYWORDS β
assert, control, do, flow, no-op, structure
π CATEGORY π
Programming tools
and that's the whole page bestie, we ate and left no crumbs π this was tcllib version 0.1.4, filed under control(3tcl) β mwah, go write some flow control, you got this π
β¨π
π¦ where this page comes from
- debian trixie: tcllib 2.0+dfsg-4 Β· Tcl
- ubuntu questing: tcllib 2.0+dfsg-4
- ubuntu resolute: tcllib 2.0+dfsg-5 Β· Tcl
- ubuntu stonking: tcllib 2.0+dfsg-6 Β· Tcl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms