• No results found

tcl,

N/A
N/A
Protected

Academic year: 2021

Share "tcl,"

Copied!
81
0
0

Loading.... (view fulltext now)

Full text

(1)

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

(2)

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

(3)

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

(4)

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

(5)

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 •

(6)

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

(7)

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

(8)

 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

(9)

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 }

(10)

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

(11)

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.

(12)

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

(13)

\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

(14)

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

(15)

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]

(16)

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

(17)

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]

(18)

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

(19)

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.

(20)

% 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.

(21)

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]

(22)

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"

(23)

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

(24)

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

(25)

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

(26)

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.

(27)

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]

(28)

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

}

(29)

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

(30)

 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.

(31)

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

(32)

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 {

(33)

}

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 }

(34)

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.

(35)

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.

(36)

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}

(37)

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

(38)

#!/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 } {

(39)

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

(40)

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.

(41)

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.

(42)

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]

(43)

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

(44)

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 ","] ":"]

(45)

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]

(46)

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 ...?

(47)

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]

(48)

%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

(49)

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

(50)

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" .]

(51)

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

(52)

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

(53)

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

(54)

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

(55)

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

(56)

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

References

Related documents