Monday, November 17, 2008

Grouping with Braces and Double Quotes

Double quotes and curly braces are used to group words together into one argument.
The difference between double quotes and curly braces is that quotes allow
substitutions to occur in the group, while curly braces prevent substitutions.
This rule applies to command, variable, and backslash substitutions.

Example 1–10 Grouping with double quotes vs. braces.
set s Hello
=> Hello
puts stdout "The length of $s is [string length $s]."
=> The length of Hello is 5.
puts stdout {The length of $s is [string length $s].}
=> The length of $s is [string length $s].
In the second command of Example 1–10, the Tcl interpreter does variable
and command substitution on the second argument to puts. In the third command,
substitutions are prevented, so the string is printed as is.
In practice, grouping with curly braces is used when substitutions on the
argument must be delayed until a later time (or never done at all). Examples
include loops, conditional statements, and procedure declarations. Double quotes
are useful in simple cases like the puts command previously shown.
Another common use of quotes is with the format command. This is similar
to the C printf function. The first argument to format is a format specifier that
often includes special characters like newlines, tabs, and spaces. The easiest way
to specify these characters is with backslash sequences (e.g., \n for newline and
\t for tab). The backslashes must be substituted before the format command is
Grouping with Braces and Double Quotes 9
I. Tcl Basics
called, so you need to use quotes to group the format specifier.
puts [format "Item: %s\t%5.3f" $name $value]
Here format is used to align a name and a value with a tab. The %s and
%5.3f indicate how the remaining arguments to format are to be formatted. Note
that the trailing \n usually found in a C printf call is not needed because puts
provides one for us. For more information about the format command, see page

Square Brackets Do Not Group
The square bracket syntax used for command substitution does not provide
grouping. Instead, a nested command is considered part of the current group. In
the command below, the double quotes group the last argument, and the nested
command is just part of that group.
puts stdout "The length of $s is [string length $s]."
If an argument is made up of only a nested command, you do not need to
group it with double-quotes because the Tcl parser treats the whole nested command
as part of the group.
puts stdout [string length $s]
The following is a redundant use of double quotes:
puts stdout "[expr $x + $y]"
Grouping before Substitution
The Tcl parser makes a single pass through a command as it makes grouping
decisions and performs string substitutions. Grouping decisions are made
before substitutions are performed, which is an important property of Tcl. This
means that the values being substituted do not affect grouping because the
grouping decisions have already been made.
The following example demonstrates how nested command substitution
affects grouping. A nested command is treated as an unbroken sequence of characters,
regardless of its internal structure. It is included with the surrounding
group of characters when collecting arguments for the main command.

Example 1–11 Embedded command and variable substitution.
set x 7; set y 9
puts stdout $x+$y=[expr $x + $y]
=> 7+9=16
In Example 1–11, the second argument to puts is:
$x+$y=[expr $x + $y]
The white space inside the nested command is ignored for the purposes of
grouping the argument. By the time Tcl encounters the left bracket, it has
already done some variable substitutions to obtain:
10 Tcl Fundamentals Chap. 1
7+9=
When the left bracket is encountered, the interpreter calls itself recursively
to evaluate the nested command. Again, the $x and $y are substituted before
calling expr. Finally, the result of expr is substituted for everything from the left
bracket to the right bracket. The puts command gets the following as its second
argument:
7+9=16

Grouping before substitution.
The point of this example is that the grouping decision about puts’s second
argument is made before the command substitution is done. Even if the result of
the nested command contained spaces or other special characters, they would be
ignored for the purposes of grouping the arguments to the outer command.
Grouping and variable substitution interact the same as grouping and command
substitution. Spaces or special characters in variable values do not affect grouping
decisions because these decisions are made before the variable values are
substituted.
If you want the output to look nicer in the example, with spaces around the
+ and =, then you must use double quotes to explicitly group the argument to
puts:
puts stdout "$x + $y = [expr $x + $y]"
The double quotes are used for grouping in this case to allow the variable and
command substitution on the argument to puts.
Grouping Math Expressions with Braces
It turns out that expr does its own substitutions inside curly braces. This is
explained in more detail on page 15. This means you can write commands like
the one below and the substitutions on the variables in the expression still occur:
puts stdout "$x + $y = [expr {$x + $y}]"
More Substitution Examples
If you have several substitutions with no white space between them, you
can avoid grouping with quotes. The following command sets concat to the value
of variables a, b, and c all concatenated together:
set concat $a$b$c
Again, if you want to add spaces, you’ll need to use quotes:
set concat "$a $b $c"
In general, you can place a bracketed command or variable reference anywhere.
The following computes a command name:
[findCommand $x] arg arg
When you use Tk, you often use widget names as command names:
$text insert end "Hello, World!"
Procedures 11

No comments: