T
Tcl cl tutorialtutorial This is
This is Tcl tutorial. In this tutorial you will learn Tcl language. The tutorial is Tcl tutorial. In this tutorial you will learn Tcl language. The tutorial is suitable for beginners.suitable for beginners.
Table of contents Table of contents
•
• Tcl languageTcl language
•
• Lexical structureLexical structure
•
• Basic commandsBasic commands
•
• ExpressionsExpressions
•
• Flow controlFlow control
• • StringsStrings • • ListsLists • • Arrays Arrays • • ProceduresProcedures • • Input/OutputInput/Output 1.Tcl 1.Tcl
Tcl is a string based scripting language. The
Tcl is a string based scripting language. The source code is compiled isource code is compiled into bytecode, which is nto bytecode, which is laterlater interpret
interpreted by the ed by the Tcl interpreteTcl interpreter. It was created by John Osterhout in 1988. The r. It was created by John Osterhout in 1988. The language is commonly language is commonly used for
used for rapid prototyping, scripted applications, GUIs and testing. The rapid prototyping, scripted applications, GUIs and testing. The Tcl stands for tool commandTcl stands for tool command language, where the source code of a T
language, where the source code of a Tcl script consists of commands.cl script consists of commands.
T Tclcl
In this part of the
In this part of the Tcl tutorial, we will introduce the Tcl programming language.Tcl tutorial, we will introduce the Tcl programming language.
Goal Goal
The goal of this
The goal of this tutorial is to get you tutorial is to get you started with the Tcl programming lanstarted with the Tcl programming language. The tutorial covers the coreguage. The tutorial covers the core of the Tcl language. Variables, lists, arrays, control structures and other core features. It is not a complete of the Tcl language. Variables, lists, arrays, control structures and other core features. It is not a complete coverage of the language. It is a quick,
coverage of the language. It is a quick, introductory materiaintroductory material. The tutorial was created on Ubuntu l. The tutorial was created on Ubuntu Linux.Linux.
Tcl is a string based scripting language. The
Tcl is a string based scripting language. The source code is compiled isource code is compiled into bytecode, which is nto bytecode, which is laterlater interpreted by the Tcl interpreter. It was created by
interpreted by the Tcl interpreter. It was created by John OsterhoutJohn Osterhout in 1988. The pin 1988. The purpose was to create aurpose was to create a language which is easily embeddable into applications. But it is often used outside
language is commonly used for rapid prototyping, scripted applications, GUIs and testing. The Tcl stands language is commonly used for rapid prototyping, scripted applications, GUIs and testing. The Tcl stands for tool command language, where the source code of a Tcl script consists
for tool command language, where the source code of a Tcl script consists of commands.of commands. Tcl is a procedural language. It has some functional features. OOP support is
Tcl is a procedural language. It has some functional features. OOP support is planned for the next officialplanned for the next official release.
release.
The official web site for both Tcl and Tk is
The official web site for both Tcl and Tk is tcl.tk tcl.tk
Popularity Popularity
There are hundreds of programming languages in use
There are hundreds of programming languages in use today. Tcl does not belong to the most popular ones.today. Tcl does not belong to the most popular ones. It has its own niche, where it used. According to the
It has its own niche, where it used. According to the langpop.comlangpop.comsite it scored 21. Onsite it scored 21. On tiobetiobeindex, it endedindex, it ended on the 96. place.
on the 96. place.
Interactive interpreter Interactive interpreter
We can run Tcl comman
We can run Tcl commands in a script or in an interacds in a script or in an interactive interprettive interpreter. In this tutorialer. In this tutorial, we will use the, we will use the
interactive Tcl session to demonstrate some smaller code fragments. Larger code examples are to be put in interactive Tcl session to demonstrate some smaller code fragments. Larger code examples are to be put in Tcl scripts.
Tcl scripts. $ tclsh $ tclsh % puts $
% puts $tcl_versiontcl_version 8.5
8.5 % puts
% puts $tcl_interact$tcl_interactiveive 11
This is
This is an example of the Tcl interactive session.an example of the Tcl interactive session. $ tclsh
$ tclsh
We start the inte
We start the interactive session with the tclsh comractive session with the tclsh command.mand. % puts $
% puts $tcl_versiontcl_version 8.5
8.5
The prompt changes to the %
The prompt changes to the % charactercharacter. We print the v. We print the value of a special tcl_version variable to the console. Italue of a special tcl_version variable to the console. It is set to the version of the current Tcl in use.
is set to the version of the current Tcl in use. % puts
% puts $tcl_interact$tcl_interactiveive 11
The tcl_interactive variabl
language is commonly used for rapid prototyping, scripted applications, GUIs and testing. The Tcl stands language is commonly used for rapid prototyping, scripted applications, GUIs and testing. The Tcl stands for tool command language, where the source code of a Tcl script consists
for tool command language, where the source code of a Tcl script consists of commands.of commands. Tcl is a procedural language. It has some functional features. OOP support is
Tcl is a procedural language. It has some functional features. OOP support is planned for the next officialplanned for the next official release.
release.
The official web site for both Tcl and Tk is
The official web site for both Tcl and Tk is tcl.tk tcl.tk
Popularity Popularity
There are hundreds of programming languages in use
There are hundreds of programming languages in use today. Tcl does not belong to the most popular ones.today. Tcl does not belong to the most popular ones. It has its own niche, where it used. According to the
It has its own niche, where it used. According to the langpop.comlangpop.comsite it scored 21. Onsite it scored 21. On tiobetiobeindex, it endedindex, it ended on the 96. place.
on the 96. place.
Interactive interpreter Interactive interpreter
We can run Tcl comman
We can run Tcl commands in a script or in an interacds in a script or in an interactive interprettive interpreter. In this tutorialer. In this tutorial, we will use the, we will use the
interactive Tcl session to demonstrate some smaller code fragments. Larger code examples are to be put in interactive Tcl session to demonstrate some smaller code fragments. Larger code examples are to be put in Tcl scripts.
Tcl scripts. $ tclsh $ tclsh % puts $
% puts $tcl_versiontcl_version 8.5
8.5 % puts
% puts $tcl_interact$tcl_interactiveive 11
This is
This is an example of the Tcl interactive session.an example of the Tcl interactive session. $ tclsh
$ tclsh
We start the inte
We start the interactive session with the tclsh comractive session with the tclsh command.mand. % puts $
% puts $tcl_versiontcl_version 8.5
8.5
The prompt changes to the %
The prompt changes to the % charactercharacter. We print the v. We print the value of a special tcl_version variable to the console. Italue of a special tcl_version variable to the console. It is set to the version of the current Tcl in use.
is set to the version of the current Tcl in use. % puts
% puts $tcl_interact$tcl_interactiveive 11
The tcl_interactive variabl
T
Tcl cl scriptsscripts
We will have our first sim
We will have our first simple example ople example of a Tcl script.f a Tcl script. #!/usr/bin/tclsh
#!/usr/bin/tclsh
# first.tcl # first.tcl
puts "This is Tcl tutorial" puts "This is Tcl tutorial" In this script, we print a
In this script, we print a message to the console.message to the console. #!/usr/bin/tclsh
#!/usr/bin/tclsh
Every script in the
Every script in the UNIX starts with a shebang. The shebang is UNIX starts with a shebang. The shebang is the first two characters in the script:the first two characters in the script: #!#!. The. The shebang is followed by the path
shebang is followed by the path to the interpreter, which will execute our script. The /usr/bin/ is to the interpreter, which will execute our script. The /usr/bin/ is the mostthe most common location for the Tcl shell. It could also be located in /usr/local/bin/ or elsewhere.
common location for the Tcl shell. It could also be located in /usr/local/bin/ or elsewhere. # first.tcl
# first.tcl
Comments in Tcl are preceded by a # character. Comments in Tcl are preceded by a # character. puts "This is Tcl tutorial"
puts "This is Tcl tutorial"
The puts
The puts command prints a string to the console.command prints a string to the console. $ which tclsh
$ which tclsh /usr/bin/tclsh /usr/bin/tclsh
The path to the Tcl interpreter can be found using the which
The path to the Tcl interpreter can be found using the which command.command. $ chmod +x
$ chmod +x first.tclfirst.tcl $ ./first.tcl
$ ./first.tcl
This is Tcl tutorial This is Tcl tutorial We make script e
We make script executable with the chmod commxecutable with the chmod command. And execute it.and. And execute it.
Sources Sources
The following sources were used to
The following sources were used to create this tutorial:create this tutorial:
•
• tcl.tk tcl.tk
•
• wikipedia.org wikipedia.org In this part of the
2.Tcl lexical structure 2.Tcl lexical structure
Computer languages, like human languages, have a lexical structure. A lexis of a
Computer languages, like human languages, have a lexical structure. A lexis of a Tcl language consists of Tcl language consists of basic element
basic elements and rules that apply to thems and rules that apply to them. Words are b. Words are basic elements in Tclasic elements in Tcl. Words can be either. Words can be either commands or command arguments
commands or command arguments. Substitution i. Substitution is one of the s one of the basic rules of the basic rules of the Tcl grammTcl grammar.ar. Commands
Commands
Tcl is a string-based, interpreted command language. A Tcl script consists of commands, which are Tcl is a string-based, interpreted command language. A Tcl script consists of commands, which are separated by newlines or semicolons. Commands are the
separated by newlines or semicolons. Commands are the basic execution elements. A command is basic execution elements. A command is followefollowedd by one or more w
by one or more words which are its argumentords which are its arguments. Each argument is separas. Each argument is separated by white space.ted by white space. A Tcl command has the fol
A Tcl command has the following form lowing form : command arg: command arg1 arg2 ar1 arg2 arg3 ... The Tcl interg3 ... The Tcl interpreter tapreter takes each word of kes each word of the sentence and evaluates it. The
the sentence and evaluates it. The first word is considered to be the first word is considered to be the command. Most Tcl commcommand. Most Tcl commands areands are variadic. This means that they can
variadic. This means that they can process variablprocess variable number of argumente number of arguments.s. When a Tcl script is parsed the c
When a Tcl script is parsed the commands are evaommands are evaluated. Each command interluated. Each command interprets words in its ownprets words in its own context.
context.
puts "Tcl language" puts "Tcl language"
In the above code excerpt, we have a
In the above code excerpt, we have a puts command. This command prints a message to the puts command. This command prints a message to the console.console. The "Tcl language" is
The "Tcl language" is a string, which is a string, which is being printed. Unlike in other languages, strings must not bebeing printed. Unlike in other languages, strings must not be enclosed in double quotes.
enclosed in double quotes. Unless there is a white space.Unless there is a white space. #!/usr/bin/tclsh
#!/usr/bin/tclsh
puts zetcode.com; puts androida.co puts zetcode.com; puts androida.co
puts zetcode puts zetcode puts androida puts androida
In the first case the commands are separated by the semicolon (;)
In the first case the commands are separated by the semicolon (;) charactercharacter. In the second . In the second case they arecase they are separated by the newline character.
separated by the newline character.
Substitution Substitution
There are three kinds of substitutions in Tcl. There are three kinds of substitutions in Tcl.
•
• Command substitutionCommand substitution •
• Variabl Variable substitutione substitution •
Square brackets are used for command substitution. % puts [expr 1+2]
3
The expr command is used to perform arithmetic calculations. First the command between the square
brackets is evaluated and the result is returned to the putscommand. The puts command then evaluates the result and prints it to the console.
If a word contains a dollar sign ($), then Tcl performs variable substitution. The dollar-sign and the following characters are replaced in the word by the value of a variable.
#!/usr/bin/tclsh
set name Jane
puts name puts $name
We create a variable called name and set a value to it. puts name
In this case, we print a string "name" to the console. puts $name
In the second case, the argument is preceded by a $ character. The value of the name variable is printed to the console.
$ ./name.tcl name
Jane
Output of the example.
With the backslash substitution, we escape the original meaning of the character. For example, the \n stands for a new line. The \t is the tab character.
% puts "This is \t Sparta" This is Sparta
Here the \t sequence is replaced with a tab. #!/usr/bin/tclsh
puts "This was a \"great\" experience"
puts "The \\ character is the backslash character"
puts "20000\b\b miles"
We use the backslash substitution, if we want to have quotes inside quote characters. Also if we want to print the \ character, we must precede it with additional backslash. The \b is substituted with a backspace. $ ./backslash.tcl
This was a "great" experience
The \ character is the backslash character 200 miles
Running the example.
Comments
Comments are used by humans to clarify the source code. In Tcl comments start with the # character. # example of a puts command
puts "Tcl language"
All characters after the # character are ignored by tclsh. puts "Tcl language" ; # example of a puts command
Inline comments are possible only if we use a semicolon.
White space
White space is used to separate words in Tcl source. It is also used to improve readability of the source code. set name Jane
The set command takes two parameters, which are separated by white space. set age 32
set name Robert
We might use more spaces if we want to improve the clarity of the source code. set vals { 1 2 3 4 5 6 7 }
puts $vals
White space is used to separate items in Tcl lists. In C based languages, we would use the comma character.
Variables
A variable is an identifier, which holds a value. In programming we say, that we assign/set a value to a variable. Technically speaking, a variable is a reference to a computer memory, where the value is stored. Variable names are case sensitive. This means, that Name, name or NAME refer to three different variables. Variables in Tcl are created with the set command. To obtain the value of a variable, its name is preceded with a $ character.
#!/usr/bin/tclsh
set name Jane set Name Julia set NAME Erika
puts $name puts $Name puts $NAME
In the above script we set three variables. The variable names are the same, they only differ in case. This practice is however not recommended.
$ ./case.tcl Jane Julia Erika Output. Braces
Braces {} have special meaning in Tcl. Substitution of words is disabled inside braces. #!/usr/bin/tclsh
set name {Julia Novak} puts $name
puts "Her name is $name" puts {Her name is $name}
This is a small script showing a usage of the braces in Tcl. set name {Julia Novak}
Braces can be used instead of double quotes to set strings separated by a white space. puts "Her name is $name"
Here the variable is substituted. puts {Her name is $name}
When using braces, the variable is not substituted. Everything is printed literally. $ ./braces.tcl
Julia Novak
Her name is Julia Novak Her name is $name
Output of the braces.tcl script.
#!/usr/bin/tclsh
set numbers { 1 2 3 4 5 6 7 } puts $numbers
puts "Braces {} are reserved characters in Tcl" puts {Braces {} are reserved characters in Tcl}
Braces are used to create lists. A list is a basic data type in Tcl. set numbers { 1 2 3 4 5 6 7 }
puts "Braces {} are reserved characters in Tcl" puts {Braces {} are reserved characters in Tcl}
Braces inside double quotes or inside other braces are taken as regular characters without special meaning. $ ./braces2.tcl
1 2 3 4 5 6 7
Braces {} are reserved characters in Tcl Braces {} are reserved characters in Tcl Output of the braces2.tcl script.
Square brackets
Square brackets, [], are used to create nested commands. These nested commands are executed before the main command on the Tcl source line. They are used to pass the result of one command as an argument to another command.
#!/usr/bin/tclsh
set cwd [pwd] puts $cwd
puts [clock format [clock seconds] -format "%Y-%m-%d %T"] In the above code example, we show some nested commands. set cwd [pwd]
The pwd command returns the current working directory of the script. It is put between the square brackets, which makes it a nested command. First the pwd command is executed and then the result of the command
is set to the cwd variable.
puts [clock format [clock seconds] -format "%Y-%m-%d %T"]
Nested commands can be nested inside other nested commands. First the clock secondsis executed. It
returns the current local time in seconds. The result is passed to the clock format command, which formats the time in a readable form. Finally, the formatted time is returned to the puts command, which prints it to the console.
$ ./nested.tcl
/home/vronskij/programming/tcl/lexis 2011-04-05 12:19:21
Output of the example.
Quotes
Double quotes group words as a single argument to commands. Dollar signs, square brackets and backslash are interpreted inside quotes.
#!/usr/bin/tclsh
set distro Ubuntu
puts "The Linux distribution name is $distro"
puts "The current working directory: [pwd]" puts "2000000\b\b\b miles"
This is a practical example of using quotes in Tcl. puts "The Linux distribution name is $distro"
The variable distro is evaluated inside the quote characters. The $distro is replaced with "Ubuntu". puts "The current working directory: [pwd]"
Commands inside square brackets are interpreted too. Here we get the current working directory with the pwd command.
puts "2000000\b\b\b miles"
The \b escape sequence deletes a preceding character. In our case three zeros are deleted. $ ./quotes.tcl
The Linux distribution name is Ubuntu
The current working directory: /home/vronskij/programming/tcl/lexis 2000 miles
Output of the quotes.tcl example.
Backslash
The backslash character can be used in three different ways in Tcl. It introduces some special characters, called escape sequences. These can be newlines, tabs, backspaces among others. It escapes the meaning of special Tcl characters ($, {}, "", \, ()). Finally, it can serve as a line continuation character.
#!/usr/bin/tclsh
puts "0\t1"
set name Jane puts \$name puts \\$name
puts "He said: \"There are plenty of them\"" puts "There are currently many Linux\
distributions in the world"
The above script shows how the backslash character can be used in Tcl. puts "0\t1"
The \t character has a special meaning in Tcl. It stands for a tab white space character. When we execute the script, 8 spaces are put inside 0 and 1.
puts \$name
With the backslash, we escape the meaning of the dollar sign. In our case $name characters are printed to the console.
puts \\$name
The backslash can be escaped too. Here the backslash character and the value of the name variable are printed to the console.
puts "He said: \"There are plenty of them\""
We can form direct speech by escaping the meaning of the inner double quotes. puts "There are currently many Linux\
distributions in the world"
If the source line is too wide, we can continue on the next line using the backslash character. Effectively escaping the newline.
$ ./backslash.tcl 0 1
\Jane
He said: "There are plenty of them"
There are currently many Linux distributions in the world Running the example.
Round brackets
Round brackets are used to indicate an array subscript or to change the precedence of operators for the expr command.
#!/usr/bin/tclsh
set names(1) Jane set names(2) Robert
puts $names(1) puts $names(2)
puts [expr (1+3)*5]
This is a simple example with round brackets in Tcl. puts $names(1)
We use the round brackets to access the value by a key which is specified inside round brackets. puts [expr (1+3)*5]
Here we change the precedence for operators. First 1 and 3 are added and then the result is multiplied by 5. In this chapter we have described the lexis of the Tcl language.
3.Basic commands in Tcl
In this part of the Tcl tutorial, we will cover some basic Tcl commands.
In the first example, we will mention the puts command. The puts command is used to print messages to the console or to other channels like a file. The command has the following syntax:
puts ?-nonewline? ?channelId? string
The puts is the command name. Optional parameters are specified between question marks. The -nonewline switch suppresses the newline character. By default, the command puts a newline to each
message. The channelId must be an identifier for an open channel such as the Tcl standard input channel (stdin), the return value from an invocation of open or socket. It defaults to stdout, if not specified. Finally the string is the message to be printed.
#!/usr/bin/tclsh
puts "This is Tcl tutorial"
puts stdout "This is Tcl tutorial"
The puts command prints a message to the console. Both command invocations do the same thing. #!/usr/bin/tclsh
puts [open messages w] "This is Tcl tutorial"
Here we use the puts command to write to a file. We open a file for writing using the opencommand. $ cat messages
This is Tcl tutorial
We show the contents of the messages file created by the above Tcl script.
Greeting a user. #!/usr/bin/tclsh
puts -nonewline "What is your name? " flush stdout
gets stdin name puts "Hello $name"
In this example, we request an input from the user and print the input in a custom greeting. puts -nonewline "What is your name? "
The -nonewline option suppresses the newline. The prompt remains on the same line. flush stdout
The output is buffered. To see the output immediately after the command runs, we can use
the flush command. The stdout is the standard output. In our case a terminal. It is called a channel id in Tcl. gets stdin name
The gets command reads a line from the standard input. The result is stored in the name variable. puts "Hello $name"
Finally, we greet the user. $ ./name.tcl
What is your name? Jan Hello Jan
Running the example.
The info command returns information about the state of the Tcl interpreter. #!/usr/bin/tclsh
puts [info tclversion] puts [info host]
puts [info exists var]
The info command has several options. We show three of them. puts [info tclversion]
Here we print the version of the Tcl interpreter. puts [info host]
This line prints the host name. puts [info exists var]
Finally we check if the variable var is set.
The set command is used to create and read variables. The unset command destroys a variable. #!/usr/bin/tclsh
set x 23 puts $x puts [set x]
unset x
puts [info exists x]
An example showing the set and unset commands. set x 23
We create an x variable and assign a value 23 to it. puts $x
We print the value of the x variable. puts [set x]
This line also prints the value of the x variable. The set command with one parameter reads the value of the variable. The value is passed to the puts command and printed to the terminal.
unset x
The variable x is destroyed. puts [info exists x]
We verify the existence of the variable using the info exists command.
Tcl scripts like any other scripts can take command line arguments. Tcl has three predefined variables.
• $argc - the number of arguments passed to the script • $argv - the list of arguments
• $argv0 - the name of the script
#!/usr/bin/tclsh
puts "The script has $argc arguments" puts "The list of arguments: $argv" puts "The name of the script is $argv0"
We use all the predefined variables in this script. $ ./args.tcl 1 2 3
The script has 3 arguments The list of arguments: 1 2 3
Running the example.
This chapter covered some basics of the Tcl language.
4.Expressions in Tcl
In this part of the Tcl tutorial, we will talk about expressions. In Tcl language the expressions are not built into the core language. Expressions are evaluated with the exprcommand.
Expressions are constructed from operands and operators. The operators of an expression indicate which operations to apply to the operands. The order of evaluation of operators in an expression is determined by the precedence and associativity of the operators.
An operator is a special symbol which indicates a certain process is carried out. Operators in programming languages are taken from mathematics. Programmers work with data. The operators are used to process data. An operand is one of the inputs (arguments) of an operator.
The following table shows a set of operators used in the Tcl language.
CategorySymbolSign, bit-wise, logical NOT- + ~ !Exponentiation**Arithmetic+ - * / %Shift<< >>Relational== != < > <= >=String comparisoneq neListin niBitwise& | ^Boolean&& ||Ternary?:
An operator usually has one or two operands. Those operators that work with only one operand are
called unary operators. Those which work with two operands are called binary operators. There is also one ternary operator (?:), which works with three operands.
Basic operators
Basic operators are commonly used operators. These are sign operators, arithmetic operators, modulo and exponentiation operators. #!/usr/bin/tclsh puts [expr +2] puts [expr -2] puts [expr -(-2)] puts [expr 2+2] puts [expr 2-2] puts [expr 2*2] puts [expr 2/2] puts [expr 2/2.0]
puts [expr 2 % 2] puts [expr 2 ** 2]
The above example shows usage of common operators in Tcl. puts [expr +2]
In this code line we use the plus sign operator. It has no effect on the number. It merely indicates that the number is positive. It can be omitted and most of the time it is.
puts [expr -2] puts [expr -(-2)]
The minus operator is compulsory. It says that the number is negative. The minus operator changes the sign of the number. In the second line, the minus operator changes the -2 to positive 2.
puts [expr 2+2] puts [expr 2-2] puts [expr 2*2] puts [expr 2/2]
The above lines show common arithmetic operators in use. puts [expr 2 % 2]
The % is the modulo or remainder operator. It finds the remainder of division of one n umber by another. 2 % 2, 2 modulo 2 is 0 because 2 goes into 2 once with the remainder of 0. So the code line prints zero to the console.
puts [expr 2 ** 2]
This is the exponentiation operator. The code line prints 4 to the console. $ ./exp.tcl 2 -2 2 4 0 4 1 1.0 0 4
Output of the example.
Division operator
Beginning programmers are often confused by division operation. In many programming languages there are two kinds of division operations. Integer and non-integer. This applies for the Tcl as well.
% expr 3/2 1
% expr 3/2.0 1.5
Note the difference between the integer and floating point division. When at least one of the operands is a floating point number, the result is a floating point value too. The result is more exact. If both operands are integers, the result is an integer too.
Assignment operator, increment operator
There is no assignment operator (=) and no increment/decrement (++/--) operators in Tcl. These operators are common in other computer languages. Instead of that, Tcl has commands.
% set a 5 5 % incr a 6 % incr a 7 % incr a -1 6
The above code shows what commands are used to implement the missing operators. % set a 5
In Python, we would do a = 5. In Tcl, we set a value to a variable using the set command. % incr a
6
In C, Java and many other languages, we would increment a variable by one this way:a++;. In Tcl, we use the incr command. By default, the value is incremented by 1.
% incr a -1 6
The above code shows how to decrement a variable by one, which is accomplished commonly by the (--) decrement operator in other languages.
Boolean operators
In Tcl, we have the following logical operators. Boolean operators are also called logical.
SymbolName&&logical and||logical or!negation#!/usr/bin/tclsh
set x 3 set y 8
puts [expr $x == $y] puts [expr $y > $x]
if {$y > $x} {
puts "y is greater than x" }
Many expressions result in a boolean value. Boolean values are used in conditional statements. puts [expr $x == $y]
puts [expr $y > $x]
Relational operators always result in a boolean value. These two lines print 0 and 1. if {$y > $x} {
puts "y is greater than x" }
The body of the if command is executed only if the condition inside the parentheses is met. The $y > $x returns true, so the message "y is greater than x" is printed to the terminal.
puts [expr 0 && 0] puts [expr 0 && 1] puts [expr 1 && 0] puts [expr 1 && 1]
Example shows the logical and (&&) operator. It evaluates to true only if both operands are true. $ ./andoperator.tcl
0 0 0 1
The logical or (||) operator evaluates to true, if either of the operands is true. #!/usr/bin/tclsh
puts [expr 0 || 0] puts [expr 0 || 1] puts [expr 1 || 0] puts [expr 1 || 1]
If one of the sides of the operator is true, the outcome of the operation is true. $ ./oroperator.tcl
0 1 1 1
The negation operator (!) makes true false and false true. #!/usr/bin/tclsh
puts [expr ! 0] puts [expr ! 1]
puts [expr ! (4<3)]
The example shows the negation operator in action. $ ./not.tcl
1 0 1
The ||, and && operators are short circuit evaluated. Short circuit evaluation means that the second argument is only evaluated if the first argument does not suffice to determine the value of the expression: when the first argument of the logical and evaluates to false, the overall value must be false; and when the
first argument of logical or evaluates to true, the overall value must be true. (wikipedia) Short circuit evaluation is used mainly to improve performance.
An example may clarify this a bit more. #!/usr/bin/tclsh
proc One {} {
puts "Inside one" return false
}
proc Two {} {
puts "Inside two" return true
}
puts "Short circuit"
puts "Pass" } puts "###################" if { [Two] || [One] } { puts "Pass" }
We have two procedures in the example. (Procedures and conditionals will be described later.) They are used as operands in boolean expressions. We will see, if they are called or not.
if { [One] && [Two] } {
puts "Pass" }
The One procedure returns false. The short circuit && does not evaluate the second procedure. It is not necessary. Once an operand is false, the result of the logical conclusion is always false. Only "Inside one" is only printed to the console.
puts "###################"
if { [Two] || [One] } {
puts "Pass" }
In the second case, we use the || operator and use the Two procedure as the first operand. In this case, "Inside two" and "Pass" strings are printed to the terminal. It is again not necessary to evaluate the second operand, since once the first operand evaluates to true, the logical or is always true.
$ ./shortcircuit.tcl Short circuit Inside one ################### Inside two Pass
Result of the shorcircuit.tcl script.
Relational Operators
Relational operators are used to compare values. These operators always result in boolean value. In Tcl 0 stands for false and 1 for true. Relational operators are also called comparison operators.
SymbolMeaning<less than<=less than or equal to>greater than>=greater than or equal to==equal to!=not equal to#!/usr/bin/tclsh
puts [expr 3 < 4] puts [expr 3 == 4] puts [expr 4 >= 3] puts [expr 4 != 3]
In Tcl we use the == to compare numbers. Some languages like Ada, Visual Basic, or Pascal u se = for comparing numbers. $ ./rel.tcl 1 0 1 1
The example prints four boolean values.
Bitwise operators
Decimal numbers are natural to humans. Binary numbers are native to computers. Binary, octal, decimal or hexadecimal symbols are only notations of the same number. Bitwise operators work with bits of a binary number. Bitwise operators are seldom used in higher level languages like Tcl.
SymbolMeaning~bitwise negation^bitwise exclusive or&bitwise and|bitwise orThe bitwise negation
operator changes each 1 to 0 and 0 to 1. % puts [expr ~7]
-8
% puts [expr ~-8] 7
The operator reverts all bits of a number 7. One of the bits also determines, whether the number is negative or not. If we negate all the bits one more time, we get number 7 again.
The bitwise and operator performs bit-by-bit comparison between two numbers. The result for a bit position is 1 only if both corresponding bits in the operands are 1.
00110 & 00011 = 00010
The first number is a binary notation of 6. The second is 3. The result is 2. % puts [expr 6 & 3]
2
% puts [expr 3 & 6] 2
The bitwise or operator performs bit-by-bit comparison between two numbers. The result for a bit position is 1 if either of the corresponding bits in the operands is 1.
00110 | 00011 = 00111
The result is 00110 or decimal 7. % puts [expr 6 | 3]
7
% puts [expr 3 | 6] 7
The bitwise exclusive or operator performs bit-by-bit comparison between two numbers. The result for a bit position is 1 if one or the other (but not both) of the corresponding bits in the operands is 1.
00110 ^ 00011 = 00101
The result is 00101 or decimal 5. % puts [expr 6 ^ 3]
5
% puts [expr 3 ^ 6] 5
Operator precedence
The operator precedence tells us which operators are evaluated first. The precedence level is necessary to avoid ambiguity in expressions.
What is the outcome of the following expression? 28 or 40? 3 + 5 * 5
Like in mathematics, the multiplication operator has a higher precedence than addition operator. So the outcome is 28.
(3 + 5) * 5
To change the order of evaluation, we can use parentheses. Expressions inside parentheses are always evaluated first.
The following table shows common Tcl operators ordered by precedence (highest precedence first):
CategorySymbolAssociativitySign, bit-wise, logical NOT- + ~ !LeftExponentiation**LeftArithmetic+ - * / %LeftShift<< >>LeftRelational== != < > <= >=LeftString comparisoneq neLeftListin niLeftBitwise& | ^LeftBoolean&& ||
LeftTernary?:RightOperators on the same row of the table have the same precedence.
!/usr/bin/tclsh
puts [expr 3 + 5 * 5] puts [expr (3 + 5) * 5]
puts [expr ! 1 || 1] puts [expr ! (1 || 1)]
In this code example, we show some common expressions. The outcome of each expression is dependent on the precedence level.
puts [expr 3 + 5 * 5]
This line prints 28. The multiplication operator has a higher precedence than addition. First the product of 5*5 is calculated. Then 3 is added.
puts [expr (3 + 5) * 5]
Round brackets can be used to change the precedence level. In the above expression, number 3 is added to 5 and the result is multiplied by 5.
In this case, the negation operator has a higher precedence. First, the first true (1) value is negated to false (0), than the || operator combines false and true, which gives true in the end.
$ ./precedence.tcl 28 40 1 0 Output. Associativity
Sometimes the precedence is not satisfactory to determine the outcome of an expression. There is another rule called associativity . The associativity of operators determines the order of evaluation of operators with the same precedence level.
9 / 3 * 3
What is the outcome of this expression? 9 or 1? The multiplication, deletion and the modulo operator are left to right associated. So the expression is evaluated this way: (9 / 3) * 3 and the result is 9.
Arithmetic, boolean, relational and bitwise operators are all left to right associated. The ternary operator is right associated.
The ternary operator
The ternary operator (?:) is a conditional operator. It is a convenient operator for cases, where we want to pick up one of two values, depending on the conditional expression.
cond-exp ? exp1 : exp2
If cond-exp is true, exp1 is evaluated and the result is returned. If the cond-exp is false, exp2 is evaluated and its result is returned.
#!/usr/bin/tclsh
set age 32
set adult [expr $age >= 18 ? true : false]
In most countries the adulthood is based on your age. You are adult if you are older than a certain age. This is a situation for a ternary operator.
set adult [expr $age >= 18 ? true : false]
First the expression on the right side of the assignment operator is evaluated. The first phase of the ternary operator is the condition expression evaluation. So if the age is greater or equal to 18, the value following the ? character is returned. If not, the value following the : character is returned. The returned value is then assigned to the adult variable.
$ ./ternary.tcl Adult: true
A 32 years old person is adult.
Calculating prime numbers
We are going to calculate prime numbers. Some of the features (lists, loops) will be covered later in the tutorial.
#!/usr/bin/tclsh
set nums { 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
}
puts "Prime numbers"
foreach num $nums {
if { $num==1 || $num==2 || $num==3 } {
puts -nonewline "$num " continue
}
set isPrime true
while { $i > 1 } {
if { $num % $i == 0 } {
set isPrime false }
incr i -1 }
if { $isPrime } {
puts -nonewline "$num " }
}
puts ""
In the above example, we deal with many various operators. A prime number (or a prime) is a natural
number that has exactly two distinct natural number divisors: 1 and itself. We pick up a number and divide it by numbers, from 1 up to the picked up number. Actually, we don't have to try all smaller numbers, we can divide by numbers up to the square root of the chosen number. The formula will work. We use the
remainder division operator.
set nums { 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
}
We will calculate primes from this list of numbers. if { $num==1 || $num==2 || $num==3 } {
puts -nonewline "$num " continue
We skip the calculations for the 1, 2, 3 numbers. They are primes. Note the usage of the equality and conditional or operators. The == has a higher precedence than the || operator. So we don't need to use parentheses.
set i [expr int(sqrt($num))]
We are OK if we only try numbers smaller than the square root of a number in question. while { $i > 1 } {
if { $num % $i == 0 } {
set isPrime false }
incr i -1 }
This is a while loop. The i is the calculated square root of the number. We use the incrcommand to to decrease the i by one each loop cycle. When the i is smaller than 1, we terminate the loop. For example, we have number 9. The square root of 9 is 3. We will divide the 9 number by 3 and 2. This is sufficient for our calculation.
if { $isPrime } {
puts -nonewline "$num " }
This is the core of the algorithm. If the remainder division operator returns 0 for any of the i values, than the number in question is not a prime.
$ ./prime.tcl Prime numbers
1 2 3 5 7 11 13 17 19 23 Output of the script.
In this part of the Tcl tutorial, we covered expressions.
5.Flow control in Tcl
In this part of the Tcl tutorial, we will talk about the flow control. We will define several commands that enable us to control the flow of a Tcl script.
In Tcl language there are several commands that are used to alter the flow of the program. When the
program is run, the commands are executed from the top of the source file to the bottom. One by one. This flow can be altered by specific commands. Commands can be executed multiple times. Some commands are conditional. They are executed only if a specific condition is met.
The if command
The if command has the following general form:
if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
The if command is used to check if an expression is true. If it is true, a body of command(s) is then executed. The body is enclosed by curly brackets.
The if command evaluates an expression. The expression must return a boolean value. In Tcl, 1, yes, true mean true and 0, no, false mean false.
!/usr/bin/tclsh
if yes {
puts "This message is always shown" }
In the above example, the body enclosed by { } characters is always executed. #!/usr/bin/tclsh
if true then {
puts "This message is always shown" }
The then command is optional. We can use it if we think, it will make the code more clear.
We can use the else command to create a simple branch. If the expression inside the square brackets following the if command evaluates to false, the command following theelse command is automatically executed.
#!/usr/bin/tclsh
if {$sex == "male"} {
puts "It is a boy" } else {
puts "It is a girl" }
We have a sex variable. It has "female" string. The boolean expression evaluates to false and we get "It is a girl" in the console.
$ ./girlboy.tcl It is a girl
We can create multiple branches using the elseif command. The elseif command tests for another condition, if and only if the previous condition was not met. Note, that we can use multiple elseif commands in our tests.
#!/usr/bin/tclsh
# nums.tcl
puts -nonewline "Enter a number: " flush stdout
set a [gets stdin]
if {$a < 0} {
puts "the number is negative" } elseif { $a == 0 } {
puts "the numer is zero" } else {
}
In the above script we have a prompt to enter a value. We test the value. If it is a negative number or positive or if it equals to zero. If the first expression evaluates to false, the second expression is evaluated. If the
previous conditions were not met, than the body following the else command would be executed. $ ./nums.tcl
Enter a number: 2 the number is positive $ ./nums.tcl
Enter a number: 0 the numer is zero $ ./nums.tcl
Enter a number: -3 the number is negative
Running the example multiple times.
The switch command
The switch command matches its string argument against each of the pattern arguments in order. As soon as it finds a pattern that matches string it evaluates the following body argument by passing it recursively to the Tcl interpreter and returns the result of that evaluation. If the last pattern argument is default then it matches anything. If no pattern argument matches string and no default is given, then the switch command returns an empty string.
#!/usr/bin/tclsh
puts -nonewline "Select a top level domain name " flush stdout
gets stdin domain
switch $domain {
us { puts "United States" } de { puts Germany }
sk { puts Slovakia } hu { puts Hungary }
default { puts unknown } }
In our script, we prompt for a domain name. There are several options. If the value equals for example to us the "United States" string is printed to the console. If the value does not match to any given value, the
default body is executed and unknown is printed to the console. $ ./switch.tcl
Select a top level domain name sk Slovakia
We have entered sk string to the console and the program responded with Slovakia.
The while command
The while command is a control flow command that allows code to be executed repeatedly based on a given boolean condition.
The while command executes the commands inside the block enclosed by the curly brackets. The commands are executed each time the expression is evaluated to true.
#!/usr/bin/tclsh # whileloop.tcl set i 0 set sum 0 while { $i < 10 } { incr i incr sum $i } puts $sum
In the code example, we calculate the sum of values from a range of numbers.
The while loop has three parts. Initialization, testing and updating. Each execution of the command is called a cycle.
set i 0
We initiate the i variable. It is used as a counter. while { $i < 10 } {
... }
The expression inside the square brackets following the while command is the second phase, the testing. The commands in the body are executed, until the expression is evaluated to false.
incr i
The last, third phase of the while loop. The updating. We increment the counter. Note that improper handling of the while loops may lead to endless cycles.
The for command
When the number of cycles is know before the loop is initiated, we can use the forcommand. In this
construct we declare a counter variable, which is automatically increased or decreased in value during each repetition of the loop.
#!/usr/bin/tclsh
for {set i 0} {$i < 10} {incr i} { puts $i
}
In this example, we print numbers 0..9 to the console. for {set i 0} {$i < 10} {incr i} {
puts $i }
There are three phases. First, we initiate the counter i to zero. This phase is done only once. Next comes the condition. If the condition is met, the command inside the for block is executed. Then comes the third
phase; the counter is increased. Now we repeat the 2, 3 phases until the condition is not met and the for loop is left. In our case, when the counter i is equal to 10, the for loop stops executing.
The foreach command simplifies traversing over collections of data. It has no explicit counter.
The foreach command goes throught the list one by one and the current value is copied to a variable defined in the construct.
#!/usr/bin/tclsh
set planets { Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune }
foreach planet $planets { puts $planet
}
In this example, we use the foreach command to go through a list of planets. foreach planet $planets {
puts $planet }
The usage of the foreach command is straightforward. The planets is the list, that we iterate through. The planet is the temporary variable, that has the current value from the list. The foreach command goes through all the planets and prints them to the console.
$ ./planets.tcl Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune
Running the above Tcl script gives this output.
#!/usr/bin/tclsh
set actresses { Rachel Weiss Scarlett Johansson Jessica Alba \ Marion Cotillard Jennifer Connelly}
foreach {first second} $actresses { puts "$first $second"
}
In this script, we iterate througn pairs of values of a list. foreach {first second} $actresses {
puts "$first $second" }
We pick two values from the list at each iteration. $ ./actresses.tcl Rachel Weiss Scarlett Johansson Jessica Alba Marion Cotillard Jennifer Connelly Output of actresses.tcl. #!/usr/bin/tclsh
foreach i { one two three } item {car coins rocks} { puts "$i $item"
}
We can iterate over two lists in parallel. $ ./parallel.tcl
one car two coins three rocks Output.
The break, continue commands
#!/usr/bin/tclsh
while true {
set r [expr 1 + round(rand()*30)] puts -nonewline "$r "
if {$r == 22} { break } }
puts ""
We define an endless while loop. We use the break command to get out of this loop. We choose a random value from 1 to 30. We print the value. If the value equals to 22, we finish the endless while loop.
set r [expr 1 + round(rand()*30)]
Here we calculate a random number between 1..30. The rand() is a built-in Tcl procedure. It returns a random number from 0 to 0.99999. The rand()*30 returns a random number between 0 to 29.99999. The round() procedure rounds the final number.
$ ./breakcommand.tcl 28 20 8 8 12 22
We might get something like this.
The continue command is used to skip a part of the loop and continue with the next iteration of the loop. It can be used in combination with for and while commands.
In the following example, we will print a list of numbers, that cannot be divided by 2 without a remainder. #!/usr/bin/tclsh
set num 0
while { $num < 100 } {
if {$num % 2 == 0} { continue }
puts "$num " }
puts ""
We iterate through numbers 1..99 with the while loop. if {$num % 2 == 0} { continue }
If the expression num % 2 returns 0, the number in question can be divided by 2. Thecontinue command is executed and the rest of the cycle is skipped. In our case, the last command of the loop is skipped and the number is not printed to the console. The next iteration is started.
In this part of the Tcl tutorial, we were talking about control flow structures.
6.Strings in Tcl
In this part of the Tcl tutorial, we will work with string data in more detail. String is an important data type in computer languages.
A string is a sequence of characters. String in Tcl, unlike in other languages, may not be enclosed within double quotes. They are necessary only if we have a space between words. Tcl is a string based language. It provides a rich set of commands for manipulating strings.
First example
A simple example showing some strings follows. #!/usr/bin/tclsh
puts Tcl puts Java puts Falcon
puts {Tcl language}
The script prints some string values to the console. puts Tcl
puts Java puts Falcon
Strings in Tcl may not be enclosed within quotes. puts "Tcl language"
puts {Tcl language}
Strings in Tcl can be grouped with double quotes or curly brackets. $ ./simple.tcl Tcl Java Falcon Tcl language Tcl language Output. Using quotes
What if we wanted to display quotes, for example in a direct speech? In such a case, inner quotes must be escaped.
$ cat directspeech.tcl #!/usr/bin/tclsh
puts "There are many stars"
puts "He said, \"Which one is your favourite?\"" We use the (\) character to escape additional quotes.
$ ./directspeech.tcl There are many stars
He said, "Which one is your favourite?" Output.
Multiline strings
It is very easy to create a multiline string in Tcl. I many other languages creating multiline strings is much less convenient.
#!/usr/bin/tclsh
set lyrics "I cheated myself like I knew I would
I told ya, I was trouble
you know that I'm no good"
puts $lyrics
We simple continue on the next line. This is useful if we wanted to display verses. $ ./multiline.tcl
I cheated myself like I knew I would I told ya, I was trouble you know that I'm no good
Comparing strings
Basic comparison of strings can be done with the string compare command. #!/usr/bin/tclsh
puts [string compare 12 12]
puts [string compare Eagle Eagle] puts [string compare Eagle eagle]
puts [string compare -nocase Eagle eagle]
The string compare command compares strings character by character. If it finds that the first characters of both strings are equal, it continues with the second character. Until the end. It returns 0, if the strings are
equal. -1 if a character in the first string is located in the ascii table before the character of the second string. 1 if the character of the first string is located after the character of the second string.
In this context, 12 is a string. puts [string compare Eagle Eagle]
Two strings are equal, 0 is printed to the console. puts [string compare Eagle eagle]
E stands before e, -1 is returned.
puts [string compare -nocase Eagle eagle]
With the -nocase option, we ignore the case. The two strings are equal. $ ./compare.tcl
0 0 -1 0
Output of the program.
The string equal also can be used to compare strings. The command returns 1, if the strings are equal, and 0 if they are not.
#!/usr/bin/tclsh
set str1 Tcl
set str2 "Tcl language"
puts [string compare $str1 $str2]
puts [string compare -length 3 $str1 $str2]
puts [string equal $str1 $str2]
puts [string equal -length 3 $str1 $str2]
The script shows both commands comparing strings. puts [string compare $str1 $str2]
The line prints -1. The characters on the first three positions are equal. On the fourth position the string compare command compares white space with the l character. The space is located before the l character in the ascii table. Strings are not equal.
puts [string compare -length 3 $str1 $str2]
In this case, we limit the comparing to first three characters. They are same in both strings, so the command returns 0.
puts [string equal $str1 $str2]
The two strings are not identical, so the string equal command returns 0, for false. puts [string equal -length 3 $str1 $str2]
Limiting strings to the first three characters, the command returns 1. Which means, they are identical up to the first three characters.
Unicode
We can use unicode strings in our Tcl scripts. #!/usr/bin/tclsh
puts "La femme vit par le sentiment, là où l'homme vit par l'action" puts "Анна Каренина"
We print two messages to the terminal. The first is in French, the second in Russian. $ ./unicode.tcl
La femme vit par le sentiment, là où l'homme vit par l'action Анна Каренина
Output.
String commands
Tcl has useful built-in commands that can be used for working with strings. #!/usr/bin/tclsh
puts [string length $str]
puts [string index $str 0] puts [string index $str end]
puts [string range $str 1 3]
We define a string variable and work with some string commands. puts [string length $str]
The string length returns the number of characters in the string. puts [string index $str 0]
puts [string index $str end]
The string index command returns the character at a specific position. puts [string range $str 1 3]
The string range returns a range of characters, selected by the first and last index. $ ./strings1.tcl 5 E e agl Output.
We have a split command to split strings at a specific character. The command returns a list of words. These words can be combined together into a string with the joincommand.
#!/usr/bin/tclsh
set langs "Tcl,Java,C,C#,Ruby,Falcon"
puts [split $langs ,]
puts [join [split $langs ","] ":"]
set langs "Tcl,Java,C,C#,Ruby,Falcon"
This is a string we are going to split. There are several words separated by a comma character. The comma character is the character, by which we will split the string.
puts [split $langs ,]
The line prints all words that we have split from the string. puts [join [split $langs ","] ":"]
The split command returns a list of words from the string. These words are then joined. The words will be now separated by the colon.
$ ./splitjoin.tcl
Tcl Java C C# Ruby Falcon Tcl:Java:C:C#:Ruby:Falcon Output of the example.
Next we will have another example with a few string commands. #!/usr/bin/tclsh
set str "ZetCode"
puts [string toupper $str] puts [string tolower $str] puts [string totitle $str] puts [string reverse $str]
We introduce four string commands. The commands do not change the original string. They return a new, modified string.
puts [string toupper $str]
We convert the characters to uppercase. puts [string tolower $str]
We convert letters of the string to lowercase. puts [string totitle $str]
The string totitle returns a string with the first character in uppercase; other characters are in lowercase. puts [string reverse $str]
We reverse the characters of the string with the string reverse command. $ ./strings2.tcl
ZETCODE zetcode Zetcode edoCteZ
Running the program.
Formatting strings
The very basic formatting of strings is done within the quotes. #!/usr/bin/tclsh
set oranges 2 set apples 4 set bananas 3
puts "There are $oranges oranges, $apples apples and\ $bananas bananas. "
Tcl evaluates variables in double quotes.
puts "There are $oranges oranges, $apples apples and\ $bananas bananas. "
In this code line, we combine variables and strings in one sentence. $ ./fruit.tcl
There are 2 oranges, 4 apples and 3 bananas. Output.
More advanced formatting can be done with the format command. It has the following synopsis. format formatString ?arg arg ...?
The formatString is used to control, how the arguments are going to be displayed. The command can take multiple arguments.
#!/usr/bin/tclsh
puts [format %s "Inception movie"] puts [format "%d %s" 23 songs]
This is basic script showing the usage of the format command. puts [format %s "Inception movie"]
This line simply prints a string to the console. puts [format "%d %s" 23 songs]
Here we print two arguments. Each argument has a format specifier, which begins with the % character. $ ./basicformat.tcl
Inception movie 23 songs
Output.
Now we show some basic conversion specifiers for the format command. %s, %f, %d, %e are conversion types. They control how the value is displayed. Conversion type is the only mandatory part of the conversion specifier.
#!/usr/bin/tclsh
puts [format "%s" "Tcl language"] puts [format "%f" 212.432]
puts [format "%d" 20000] puts [format "%e" 212.342]
We will print four messages to the terminal. puts [format "%s" "Tcl language"]
The %s is a conversion type for the string. puts [format "%f" 212.432]
%f is used to display decimal numbers. puts [format "%d" 20000]
To print an integer value, we use the %d conversion type. puts [format "%e" 212.342]
The %e is used to show number in a scientific format. $ ./format.tcl Tcl language 212.432000 20000 2.123420e+02 Output.
In the next example, we will be formatting numbers in three different number formats. #!/usr/bin/tclsh
puts [format "%-10s %-14s %s" Decimal Hexadecimal Octal]
puts [format "%-10d %-14x %o" 5000 5000 5000] puts [format "%-10d %-14x %o" 344 344 344] puts [format "%-10d %-14x %o" 55 55 55] puts [format "%-10d %-14x %o" 9 9 9]
puts [format "%-10d %-14x %o" 15666 15666 15666]
We print numbers in a decimal, hexadecimal and octal format. We also align the numbers in three columns. puts [format "%-10d %-14x %o" 5000 5000 5000]
The %-10d applies for the first number, %-14x for the second and %o for the third. We will describe the first one. The format specifier begins with the % character. The minus sign (-) tells, that if the value will be
shorter than the field width, it is left justified. The rest of the field is padded with w hite space. The number (10) specifies the field width. Finally the d character tells that the number is displayed in decimal format. The x stands for hexadecimal and o for octal.
$ ./numbers.tcl
5000 1388 11610
344 158 530
55 37 67
9 9 11
15666 3d32 36462 Running the example.
Finally, we will format date and time data. We use the clock format command. #!/usr/bin/tclsh
set secs [clock seconds]
puts "Short date: [clock format $secs -format %D]"
puts "Long date: [clock format $secs -format "%A, %B %d, %Y"]" puts "Short time: [clock format $secs -format %R]"
puts "Long time: [clock format $secs -format %r]" puts "Month: [clock format $secs -format %B]" puts "Year: [clock format $secs -format %Y]"
The preceding example demonstrates some common date and time formats. set secs [clock seconds]
We get the current timestamp in seconds. This value is later passed to the clock formatcommand, to get dates and times readable for humans.
puts "Short date: [clock format $secs -format %D]"
The format of the date is controlled with the -format option. There are several specifiers. The %D returns a date in month/day/year format.
$ ./clockformat.tcl Short date: 04/11/2011
Long date: Monday, April 11, 2011 Short time: 11:30
Long time: 11:30:30 am Month: April
Output.
This part of the Tcl tutorial covered strings.
7.Tcl lists
In this part of the Tcl tutorial, we will talk about lists.
Computer programs work with data. Spreadsheets, text editors, calculators or chat clients. Working with groups of data is a basic programming operation. In Tcl, the list is a basic data structure. It is an ordered collection of items. Items in lists are separated by white space.
Every item of the list is identified by its index. Lists do not have a fixed length. List elements can be strings, numbers, variables, files or other lists. We can nest lists into other lists to any depth.
Creating lists
There are several ways, how we can create lists in Tcl. #!/usr/bin/tclsh
set l1 { 1 2 3 }
set l2 [list one two three] set l3 [split "1.2.3.4" .]
puts $l1 puts $l2 puts $l3
We create tree lists and print their contents to the console. set l1 { 1 2 3 }
The basic way to create a list is to put elements of the list inside the brackets. List elements are separated by space.
set l2 [list one two three]
Another way to create a list is to use the list command. set l3 [split "1.2.3.4" .]
Some Tcl commands return a list as a result. In the above code line, the split command returns a list of numbers generated from a string.
$ ./createlists.tcl 1 2 3
one two three 1 2 3 4
Output of the createlists.tcl script.
Basic list operations
In this section, we introduce some basic operations on lists. We will mention tree commands, that operate on Tcl lists.
#!/usr/bin/tclsh
set nums { 1 2 3 4 5 6 7 }
puts [llength $nums] puts [lindex $nums 2] puts [lindex $nums 4] puts [lrange $nums 1 3]
The script defines a list of numbers. We perform some operations on the list with specific list commands. puts [llength $nums]
The llength command returns a length of the list. puts [lindex $nums 2]
The lindex command returns an item on the third position of the list. The positions in Tcl lists start from 0. puts [lrange $nums 1 3]
The lrange command returns a subset of the list. $ ./basicoperations.tcl
7 3 5 2 3 4
Output.
Traversing lists
Now that we have defined lists and basic list operations, we want to go traverse the list elements. We show several ways how to go through the list items.
#!/usr/bin/tclsh
foreach item {1 2 3 4 5 6 7 8 9} {
puts $item }
We go through list elements with the foreach command. foreach item {1 2 3 4 5 6 7 8 9} {
puts $item }
Each loop cycle the item variable has a value from the list of numbers. $ ./traverse1.tcl 1 2 3 4 5 6 7 8 9 Ouput.
In the second example we will go through items of the days list using the while loop. #!/usr/bin/tclsh
set days [list Monday Tuesday Wednesday Thursday \ Friday Saturday Sunday]
set n [llength $days]
set i 0
while {$i < $n} {
puts [lindex $days $i] incr i
}
We traverse the list using a while loop. When working with a while loop, we also need a counter and a number of items in the list.
set days [list Monday Tuesday Wednesday Thursday \ Friday Saturday Sunday]
We create a list of days. set n [llength $days]
The length of the list is determined with the llength command. set i 0
The is a counter. while {$i < $n} {
puts [lindex $days $i] incr i
}
The while loop executes the commands in the body, until the counter is equal to the number of elements in the list.
puts [lindex $days $i]
The lindex returns a value from the list pointed to by the counter. incr i
The counter is increased. $ ./traverse2.tcl Monday Tuesday Wednesday Thursday Friday Saturday Sunday Output. List operations
Now we will have some other list commands. #!/usr/bin/tclsh
set nums {4 5 6} puts $nums
lappend nums 7 8 9 puts $nums
puts [linsert $nums 0 1 2 3] puts $nums
We have a list of three numbers. lappend nums 7 8 9
The lappend appends data to the list. puts [linsert $nums 0 1 2 3]
The linsert inserts elements at a given index. The first number is the index. The remaining values are
numbers to be inserted into the list. The command creates a new lists and returns it. It does not modify the original list.
$ ./operations.tcl 4 5 6
4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 4 5 6 7 8 9
This is the output of the operations.tcl script.
In the following example, we will concatenate lists, search for items and replace items in lists. #!/usr/bin/tclsh
set animals1 { lion eagle elephant dog cat } set animals2 { giraffe tiger horse dolphin }
set animals [concat $animals1 $animals2]
puts $animals
puts [lsearch -exact $animals eagle]
puts [lreplace $animals 3 4 buffalo crocodile]
We define two animal lists. We introduce three new commands. set animals [concat $animals1 $animals2]
The concat command is used to concatenate (add) two lists. The above line joins two lists and the new list is set to the animals variable.
puts [lsearch -exact $animals eagle]
With the lsearch command we look for an eagle in the list. With the -exact option we look for an exact match. The command returns the index of the first matching element. Or -1 if there is no match.
puts [lreplace $animals 3 4 buffalo crocodile]
The lreplace command replaces dog and cat with buffalo and crocodile. $ ./operations2.tcl
lion eagle elephant dog cat giraffe tiger horse dolphin 1
Example output.
Sorting items
In this section, we will show how we can sort items in Tcl lists. #!/usr/bin/tclsh
set names { John Mary Lenka Veronika Julia Robert } set nums { 1 5 4 3 6 7 9 2 11 0 8 2 3 }
puts [lsort $names]
puts [lsort -ascii $names]
puts [lsort -ascii -decreasing $names] puts [lsort -integer -increasing $nums] puts [lsort -integer -decreasing $nums] puts [lsort -integer -unique $nums]
To sort list elements, we can use the sort command. The command does not modify the original list. It returns a new sorted list of elements.
set names { John Mary Lenka Veronika Julia Robert } set nums { 1 5 4 3 6 7 9 2 11 0 8 2 3 }
We have two lists. In the first we have strings, in the second numbers. puts [lsort $names]
puts [lsort -ascii $names]
The default sorting is the ascii sorting. The elements are sorted by their positions in the ascii table. puts [lsort -integer -increasing $nums]
puts [lsort -integer -decreasing $nums]
We treat the values as integers and sort them in increasing and decreasing orders. puts [lsort -integer -unique $nums]
We sort the elements of the list in a numerical context in increasing order. Duplicates will be removed. $ ./sorting.tcl