---
name: "control"
section: "3tcl"
platform: "linux"
package: "tcllib"
version: "2.0+dfsg-4"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/control"
---

# control(3tcl)

Procedures for control flow structures.

```

```

## NAME

control - Procedures for control flow structures.

## 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

The **control** package provides a variety of commands that provide additional flow of control structures beyond the built-in ones provided by Tcl.  These are commands that in many programming languages might be considered *keywords*, or a part of the language itself.  In Tcl, control flow structures are just commands like everything else.

## COMMANDS

- **control::control** *command* *option* ?*arg arg ...*?

  The **control** command is used as a configuration command for customizing the other public commands of the control package.  The *command* argument names the command to be customized.  The set of valid *option* and subsequent arguments are determined by the command being customized, and are documented with the command.

- **control::assert** *expr* ?*arg arg ...*?

  When disabled, the **assert** command behaves exactly like the **no-op** command.

  When enabled, the **assert** command evaluates *expr* as an expression (in the same way that **expr** evaluates its argument). If evaluation reveals that *expr* is not a valid boolean expression (according to \[**string is boolean -strict**\]), an error is raised.  If *expr* evaluates to a true boolean value (as recognized by **if**), then **assert** returns an empty string.  Otherwise, the remaining arguments to **assert** are used to construct a message string.  If there are no arguments, the message string is "assertion failed: $expr".  If there are arguments, they are joined by **join** to form the message string.  The message string is then appended as an argument to a callback command, and the completed callback command is evaluated in the global namespace.

  The **assert** command can be customized by the **control** command in two ways:

  \[**control::control assert enabled** ?*boolean*?\] queries or sets whether **control::assert** is enabled.  When called without a *boolean* argument, a boolean value is returned indicating whether the **control::assert** command is enabled.  When called with a valid boolean value as the *boolean* argument, the **control::assert** command is enabled or disabled to match the argument, and an empty string is returned.

  \[**control::control assert callback** ?*command*?\] queries or sets the callback command that will be called by an enabled **assert** on assertion failure.  When called without a *command* argument, the current callback command is returned. When called with a *command* argument, that argument becomes the new assertion failure callback command.  Note that an assertion failure callback command is always defined, even when **assert** is disabled.  The default callback command is \[**return -code error**\].

  Note that **control::assert** has been written so that in combination with \[**namespace import**\], it is possible to use enabled **assert** commands in some namespaces and disabled **assert** commands in other namespaces at the same time.  This capability is useful so that debugging efforts can be independently controlled module by module.

  ```
  % 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** *body* ?*option test*?

  The **do** command evaluates the script *body* repeatedly *until* the expression *test* becomes true or as long as (*while*) *test* is true, depending on the value of *option* being **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 in the same way the **while** command handles them, except as noted in **LIMITATIONS**, below.

- **control::no-op** ?*arg arg ...*?

  The **no-op** command takes any number of arguments and does nothing.  It returns an empty string.

## LIMITATIONS

Several of the commands provided by the **control** package accept arguments that are scripts to be evaluated.  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*.  In this way, the commands of the **control** package are limited as compared to Tcl's built-in control flow commands (such as **if**, **while**, etc.) and 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
```

## BUGS, IDEAS, FEEDBACK

This document, and the package it describes, will undoubtedly contain bugs and other problems. Please report such in the category *control* of the *Tcllib Trackers* \[http://core.tcl.tk/tcllib/reportlist\]. Please also report any ideas for enhancements you may have for either package and/or documentation.

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
