tcl,

Share Embed Donate


Short Description

basic tcl...

Description

Tcl tutorial

This is Tcl tutorial. In this tutorial you will learn Tcl language. The tutorial is suitable for beginners.

Table of contents •

Tcl language



Lexical structure



Basic commands



Expressions



Flow control



Strings



Lists



 Arrays



Procedures



Input/Output

1.Tcl

Tcl is a string based scripting language. The source code is compiled into i nto bytecode, which is later interpreted interpreted by the Tcl interpreter. interpreter. It was created by John Osterhout in 1988. The 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 T cl script consists of commands.

Tcl

In this part of the Tcl tutorial, we will introduce the Tcl programming language.

Goal

The goal of this tutorial is to get you started with the Tcl programming language. language. The tutorial covers the core 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, introductory material. material. The tutorial was created on Ubuntu Linux.

Tcl is a string based scripting language. The source code is compiled into i nto bytecode, which is later interpreted by the Tcl interpreter. It was created by John by  John Osterhout in 1988. The purpose p urpose was to create a language which is easily embeddable into applications. But it is often used outside its original area. The

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 of commands. Tcl is a procedural language. It has some functional features. OOP support is planned for the next official release. The official web site for both Tcl and Tk is tcl.tk 

Popularity

There are hundreds of programming languages in use today. Tcl does not belong to the most popular ones. It has its own niche, where it used. According to the langpop.com langpop.comsite site it scored 21. On tiobe index, it ended on the 96. place.

Interactive interpreter

 We can run Tcl commands commands in a script or in an interactive interactive interpreter. interpreter. In this tutorial, tutorial, we will use the interactive Tcl session to demonstrate some smaller code fragments. Larger code examples are to be put in Tcl scripts. $ tclsh % puts $tcl_version $ tcl_version 8.5 % puts $tcl_interactive $tcl_interactive 1 This is an example of the Tcl interactive session. $ tclsh  We start the interactive interactive session with the tclsh command. command. % puts $tcl_version $ tcl_version 8.5 The prompt changes to the % character. character. We print the value v alue of a special tcl_version variable to the console. It is set to the version of the current Tcl in use. % puts $tcl_interactive $tcl_interactive 1 The tcl_interactive variable variable tells us whether we are in an interactive mode or not.

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 of commands. Tcl is a procedural language. It has some functional features. OOP support is planned for the next official release. The official web site for both Tcl and Tk is tcl.tk 

Popularity

There are hundreds of programming languages in use today. Tcl does not belong to the most popular ones. It has its own niche, where it used. According to the langpop.com langpop.comsite site it scored 21. On tiobe index, it ended on the 96. place.

Interactive interpreter

 We can run Tcl commands commands in a script or in an interactive interactive interpreter. interpreter. In this tutorial, tutorial, we will use the interactive Tcl session to demonstrate some smaller code fragments. Larger code examples are to be put in Tcl scripts. $ tclsh % puts $tcl_version $ tcl_version 8.5 % puts $tcl_interactive $tcl_interactive 1 This is an example of the Tcl interactive session. $ tclsh  We start the interactive interactive session with the tclsh command. command. % puts $tcl_version $ tcl_version 8.5 The prompt changes to the % character. character. We print the value v alue of a special tcl_version variable to the console. It is set to the version of the current Tcl in use. % puts $tcl_interactive $tcl_interactive 1 The tcl_interactive variable variable tells us whether we are in an interactive mode or not.

Tcl scripts

 We will have our first simple simple example of of a Tcl script. #!/usr/bin/tclsh

# first.tcl

puts "This is Tcl tutorial" In this script, we print a message to the console. #!/usr/bin/tclsh Every script in the UNIX starts with a shebang. The shebang is the first two characters in the script: #!. #!. The shebang is followed by the path to the interpreter, which will execute our script. The /usr/bin/ is the most common location for the Tcl shell. It could also be located in /usr/local/bin/ or elsewhere. # first.tcl Comments in Tcl are preceded by a # character. puts "This is Tcl tutorial" The puts command prints a string to the console. $ which tclsh /usr/bin/tclsh The path to the Tcl interpreter can be found using the which command. $ chmod +x first.tcl $ ./first.tcl This is Tcl tutorial  We make script executable executable with the chmod command. command. And execute it.

Sources

The following sources were used to create this tutorial: • •

tcl.tk   wikipedia.org

In this part of the Tcl tutorial, we have introduced the Tcl language.

2.Tcl lexical structure

Computer languages, like human languages, have a lexical structure. A lexis of a Tcl language consists of   basic elements elements and rules that apply to them. them. Words are basic basic elements in Tcl. Tcl. Words can be either commands or command arguments. arguments. Substitution is i s one of the basic rules of the Tcl grammar. grammar. Commands

Tcl is a string-based, interpreted command language. A Tcl script consists of commands, which are separated by newlines or semicolons. Commands are the basic execution elements. A command is followed followed  by one or more words words which are its arguments. arguments. Each argument is separated separated by white space.  A Tcl command has the following following form : command arg1 arg1 arg2 arg3 arg3 ... The Tcl interpreter interpreter takes takes each word of  the sentence and evaluates it. The first word is considered to be the command. Most Tcl commands commands are  variadic. This means that they can process variable variable number of arguments. arguments.  When a Tcl script is parsed the commands commands are evaluated. evaluated. Each command interprets interprets words in its own context. puts "Tcl language" In the above code excerpt, we have a puts command. This command prints a message to the console. The "Tcl language" is a string, which is being printed. Unlike in other languages, strings must not be enclosed in double quotes. Unless there is a white space. #!/usr/bin/tclsh

puts zetcode.com; puts androida.co

puts zetcode puts androida In the first case the commands are separated by the semicolon (;) character. character. In the second case they are separated by the newline character.

Substitution

There are three kinds of substitutions in Tcl. • • •

Command substitution  Variable  Variable substitution Backslash 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 set name

32 Robert

set occupation programmer

 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 } Here a list of numbers is created.

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

$name

\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 The name of the script is ./args.tcl

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. CategorySymbol Sign, 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.

#!/usr/bin/tclsh

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

operator changes each 1 to 0 and 0 to 1. % puts [expr ~7] -8 % puts [expr ~-8] 7

negation

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): CategorySymbolAssociativity Sign, 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. puts [expr ! 1 || 1]

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]

puts "Adult: $adult"

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 i [expr int(sqrt($num))]

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

set sex female

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 {

puts "the number is positive"

} 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

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

The break command can be used to terminate a block defined by while, for or switchcommands.

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

incr num

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"

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. puts [string compare 12 12]

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

set str Eagle

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 ","] ":"] In our program, we will split and join strings.

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 Decimal

Hexadecimal

Octal

5000

1388

344

158

55

37

9

9

15666

11610 530 67 11

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  Year: 2011

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 123 one two three 1234 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 234

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 456

456789 123456789 456789 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 lion eagle elephant buffalo crocodile giraffe tiger horse dolphin

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 John Julia Lenka Mary Robert Veronika

John Julia Lenka Mary Robert Veronika  Veronika Robert Mary Lenka Julia John 0 1 2 2 3 3 4 5 6 7 8 9 11 11 9 8 7 6 5 4 3 3 2 2 1 0 0 1 2 3 4 5 6 7 8 9 11 Output.

Nested lists

In Tcl there can be nested lists; list in other lists. #!/usr/bin/tclsh set nums {1 2 {1 2 3 4} {{1 2} {3 4}} 3 4} puts [llength $nums] puts [llength [lindex $nums 2]] puts [lindex $nums 0] puts [lindex [lindex $nums 2] 1] puts [lindex [lindex [lindex $nums 3] 1] 1] This is a simple example with nested lists in Tcl. set nums {1 2 {1 2 3 4} {{1 2} {3 4}} 3 4}  A list with two nested lists. The second list has two additional inner nested lists. puts [llength $nums]  We determine the size of the list. The nested list is counted as one element. puts [llength [lindex $nums 2]] In this line, we determine the size of the first nested list, which is the third element of the main list. puts [lindex $nums 0] Here we print the first element of the main list. puts [lindex [lindex $nums 2] 1] In the above line, we get the second element of the first nested list.

puts [lindex [lindex [lindex $nums 3] 1] 1] Here we get the second element of the second inner list of the inner list located at the 4th position of the main list. In other words: the inner most command is executed first. The [lindex $nums 3] returns {{1 2} {3 4}}. Now the second command operates on this returned list. [lindex {{1 2} {3 4}} 1] returns {3 4}. Finally, the last command [lindex {3 4} 1]returns 4, which is printed to the terminal. $ ./nestedlists.tcl 6 4 1 2 4 Output. In this part of the Tcl tutorial, we covered Tcl lists. 8.Arrays

in Tcl

In this part of the Tcl programming tutorial, we will cover arrays. We will initiate arrays and read data from them.  An array in Tcl is a data structure, which binds a key with a value. A key and a value can be any Tcl string. #!/usr/bin/tclsh

set names(1) Jane set names(2) Tom set names(3) Elisabeth set names(4) Robert set names(5) Julia set names(6) Victoria

puts [array exists names] puts [array size names]

puts $names(1) puts $names(2) puts $names(6)

 We create a names array. The numbers are keys and the names are values of the array. set names(1) Jane In this line we set a value Jane to the array key 1. We can later refer to the value by the key. puts [array exists names] The array exists command determines, whether the array is created. Returns 1 if true, 0 otherwise. puts [array size names]  We get the size of the array with the array size command. puts $names(1)  We access a value from the array by its key. $ ./names.tcl 1 6 Jane Tom  Victoria Output.

 Arrays can be initiated with the array set command. #!/usr/bin/tclsh

array set days { 1 Monday  2 Tuesday  3 Wednesday  4 Thursday  5 Friday  6 Saturday  7 Sunday  }

foreach {n day} [array get days] {

puts "$n -> $day" }  We create a day array. It has 7 keys and values. foreach {n day} [array get days] { The array get command returns a list of key, value elements, which can be iterated with the foreach command. $ ./days.tcl 4 -> Thursday  5 -> Friday  1 -> Monday  6 -> Saturday  2 -> Tuesday  7 -> Sunday  3 -> Wednesday  Output.

 We show another way to traverse an array in Tcl. #!/usr/bin/tclsh

array set nums { a 1 b 2 c 3 d 4 e 5 }

puts [array names nums]

foreach n [array names nums] {

puts $nums($n) } The script uses the array names command to traverse the array. array set nums { a 1 b 2 c 3 d 4 e 5 }

 We define a simple array. puts [array names nums] The array names returns a list containing the names of all of the elements in the array. foreach n [array names nums] { puts $nums($n) }  We use the keys to get the values. $ ./getnames.tcl deabc 4 5 1 2 3 Output.

In the last example of this chapter, we will show how to remove elements from the array. #!/usr/bin/tclsh

set names(1) Jane set names(2) Tom set names(3) Elisabeth set names(4) Robert set names(5) Julia set names(6) Victoria

puts [array size names] unset names(1) unset names(2)

puts [array size names]  We create a names array. We use the unset command to remove items from the array. We check the size of  the array before and after we remove the two items. set names(1) Jane The set command is used to create an item in the array. unset names(1)  We use the unset command to remove an element with key 1 from the array. In this part of the Tcl tutorial, we worked with arrays.

10.Procedures in Tcl

In this part of the tutorial, we will cover Tcl procedures.  A procedure is a code block containing a series of commands. Procedures are called functions in some programming languages. It is a good programming practice that procedures do only one specific task. Procedures bring modularity to programs. Proper use of procedures bring the following advantages: •

Reducing duplication of code



Decomposing complex problems into simpler pieces



Improving clarity of the code



Reuse of code



Information hiding

There are two basic types of procedures. Built-in procedures and user defined ones. The built-in procedures are part of the Tcl core language. Examples are: rand(), sin() or exp(). The user defined functions are functions created with the proc keyword. The term procedures and commands are often used interchangeably. In other words, the proc keyword is used to create new Tcl commands.  We start with a simple example. #!/usr/bin/tclsh

proc tclver {} {

set v [info tclversion] puts "this is tcl version $v"

}

tclver In this script, we create a simple tclver procedure. The procedure prints the version of Tcl language. proc tclver {} { The new procedure is created with the proc command. The {} characters tell us, that the procedure takes no arguments. { set v [info tclversion] puts "this is tcl version $v" } This is the body of the tclver procedure. It is executed, when we execute the tclver command. The body of  the command lies between the curly brackets. tclver The procedure is called by specifying its name. $ ./version.tcl this is tcl version 8.5 Sample output.

Procedure arguments

 An argument is a value passed to the procedure. Procedures can take one or more arguments. If procedures  work with data, we must pass the data to the procedures. In the following example, we have a procedure which takes one argument. #!/usr/bin/tclsh

proc ftc {f} {

return [expr $f * 9 / 5 + 32] }

puts [ftc 100] puts [ftc 0] puts [ftc 30]  We create a ftc procedure, which transforms fahrenheit temperature to celsius temperature. proc ftc {f} { The procedure takes one parameter. Its name f will be used in the body of the procedure. return [expr $f * 9 / 5 + 32]  We compute the value of the celsius temperature. The return command returns the value to the caller. If the procedure doesn't execute an explicit return, then its return value is the value of the last command executed in the procedure's body. puts [ftc 100] The ftc procedure is executed. It takes 100 as a parameter. It is the temperature in fahrenheit. The returned  value is used by the puts command, which prints it to the console. $ ./fahrenheit.tcl 212 32 86 Output.

Next we will have a procedure, which takes two arguments. #!/usr/bin/tclsh

proc maximum {x y} {

if {$x > $y} {

return $x } else {

return $y 

} }

set a 23 set b 32

set val [maximum $a $b] puts "The max of $a, $b is $val"  We have a maximum procedure, which returns the maximum of two values. proc maximum {x y} { The method takes two arguments. if {$x > $y} { return $x } else { return $y  } Here we compute which number is greater. set a 23 set b 32  We define two variables, which are to be compared. set val [maximum $a $b]  We calculate the maximum of the two variables. $ ./maximum.tcl The max of 23, 32 is 32 Output.

Variable number of arguments

 A procedure can take and process variable number of arguments. For this we use the special args argument.

#!/usr/bin/tclsh

proc sum {args} {

set s 0

foreach arg $args {

incr s $arg }

return $s }

puts [sum 1 2 3 4] puts [sum 1 2] puts [sum 4]  We define a sum procedure which adds up all its arguments. proc sum {args} { The sum procedure has a special args argument. It has a list of all values passed to the procedure. foreach arg $args { incr s $arg }  We go through the list and calculate the sum. puts [sum 1 2 3 4] puts [sum 1 2] puts [sum 4]  We call the sum procedure three times. In the first case, it takes 4 arguments, in the second case 2, in the last case one. We call the same method. $ ./variable.tcl

10 3 4 Output.

Implicit arguments

The arguments in Tcl procedures may have implicit values. An implicit value is used, if no explicit value is provided. #!/usr/bin/tclsh

proc power {a {b 2}} {

if {$b == 2} { return [expr $a * $a] }

set value 1

for {set i 0} {$i $mx} {

set mx $len } }

set fstr "%-$mx\s %-s" puts [format $fstr Name Size]

set fstr "%-$mx\s %d bytes" foreach fl $files {

set size [file size $fl]

puts [format $fstr $fl $size]

} The script creates two columns. In the first column, we have the name of the file. In the second column, we display the size of the file. foreach fl $files { set len [string length $fl] if { $len > $mx} {

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF