control(n)
π control(n) β the Tcl Control Flow Commands era π
okay bestie, sit down, we're talking about the control package, no cap. it lives in the control(n) manual, it's giving "extra control flow structures for Tcl," and honestly? it ate. β¨
πΈ NAME πΈ
control β Procedures for control flow structures. literally that's the whole vibe. π¦
β¨ 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 ...?
look at her. four little commands and a package requirement. main character energy fr fr. π
π DESCRIPTION π
The control package hands you a whole lineup of commands that give you additional flow of control structures beyond the built-in ones Tcl already ships with. like, these are the things that in a lot of other programming languages would be keywords, or baked straight into the language itself. π
but Tcl said "no β€οΈ" β in Tcl, control flow structures are just commands like everything else. periodt. that's the whole philosophy and we respect it deeply. π
π COMMANDS π
control::control command option ?arg arg ...?
so control here is the configuration command, aka the lil settings panel for all the other public commands in the package. the command argument names which command you're customizing. π§
the set of valid options and the arguments that come after them is decided by the command being customized, and each one documents its own stuff. so go read that command's section, bestie, it's all there. π
control::assert expr ?arg arg ...?
when it's disabled, assert behaves exactly like the no-op command. like, a whole nothing-burger. π
when it's enabled, though? oh she's working. assert evaluates expr as an expression β same way expr evaluates its own argument. then:
- if the evaluation reveals that
exprisn't a valid boolean expression (according to[string is boolean -strict]), an error is raised. π - if
exprevaluates to a true boolean value (as recognized byif), thenassertreturns an empty string. cute, clean, done. β¨ - otherwise, the remaining arguments to
assertget used to construct a message string:- if there are no arguments, the message string is
"assertion failed: $expr". - if there are arguments, they're joined by
jointo form the message string.
- if there are no arguments, the message string is
then the message string gets appended as an argument to a callback command, and that completed callback command is evaluated in the global namespace. π«Ά
now, assert can be customized by the control command in two ways:
[control::control assert enabled ?boolean?]β queries or sets whethercontrol::assertis enabled. called without abooleanargument, you get back a boolean value telling you whether thecontrol::assertcommand is enabled. called with a valid boolean value as thebooleanargument, thecontrol::assertcommand is enabled or disabled to match, and an empty string comes back at you.[control::control assert callback ?command?]β queries or sets the callback command that an enabledassertwill call on assertion failure. called without acommandargument, you get the current callback command. called with acommandargument, that argument becomes the new assertion failure callback command. heads up: an assertion failure callback command is always defined, even whenassertis disabled. the default callback command is[return -code error].
not me being obsessed with this next part:control::assertwas 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. π so useful β it means debugging efforts can be independently controlled module by module. iykyk.
% 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}
see how one::assert screamed and two::assert said absolutely nothing? that's the whole point, bestie. π
control::do body ?option test?
do evaluates the script body repeatedly until the expression test becomes true, or 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.) during the evaluation of body are handled the same way the while command handles them β except as noted in LIMITATIONS below. go read that bit, it matters. π
control::no-op ?arg arg ...?
takes any number of arguments and does nothing. returns an empty string. she's just standing there, existing, thriving, contributing nothing. iconic. π
π LIMITATIONS π
Several of the commands in the control package accept arguments that are scripts to be evaluated. but due to fundamental limitations of Tcl's catch and return commands, it is not possible for these commands to properly evaluate the command [return -code $code] within one of those script arguments for any value of $code other than ok. π«
so yeah β the commands of the control package are limited compared to Tcl's built-in control flow commands (like if, while, etc.) and compared to those control flow commands that can be provided by packages coded in C. an example of this difference:
% 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
a catches as 1, b catches as 0. that's the difference. not me crying over $code values. π
π BUGS, IDEAS, FEEDBACK π
ngl, this document β and the package it describes β will undoubtedly contain bugs and other problems. it's giving "we're all just doing our best." π
please report such things in the category control of the Tcllib Trackers at [http://core.tcl.tk/tcllib/reportlist]. and please also report any ideas for enhancements you may have for either the package and/or the documentation. we want them fr fr. π«Ά
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. slay, thank you. β¨
π SEE ALSO π
break, continue, expr, if, join, namespace, return, string, while
the whole squad. all present and accounted for. π
β KEYWORDS β
assert, control, do, flow, no-op, structure
π CATEGORY π
Programming tools
and that's the page, bestie!! written by tcllib, version 0.1.4, filed under control(n) β go forth and assert responsibly, enable your callbacks, and remember: in Tcl, control flow is just commands like everything else. π
β¨π¦π
π¦ where this page comes from
- fedora 43: tcllib 2.0-3.fc43 Β· TCL
- fedora 44: tcllib 2.0-4.fc44 Β· TCL
- nixos 26.05: tcllib 2.0
- nixpkgs unstable: tcllib 2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms