So you've got the basics down. You know how to use the console, you've got a clue what happens when you type stuff in and maybe an inkling as to what's going on under the hood. It's time to let your creative juices rip and start programming. Well, almost. First you're going to need to know a few rules about just how Tcl works, and a few of its quirks. If you're totally unfamiliar with programming, you'll probably want to read through all of these once and mess around with the ones you understand or almost do. Then go on to commands, try writing some scripts and come back here when you're more familiar with the rest of the language. While these are all pretty important, I'd really advise not leaving this page until you understand the ones marked with an asterix (*) as they are more or less key to any program. Note that by far the best way to learn, is to try it yourself. TYPE THE EXAMPLES INTO WISH AND SEE WHAT HAPPENS. You will learn a lot the first time you make a typo, trust me.
We'll cover (in this order):
*Comments
*Substitution
*Quotes Vs. Curly Braces
Lists
Arrays
List of Operators
*If/Then Else
Loops
Procedures
Comments
At some point you're going to want to build an actual program, and at that point you're going to stop typing in the commands one line at a time. You'll save all the commands into a script, and Tcl will run through them at once. This will be wonderful, except for when you want to go back and change something. Suddenly you're faced with a bunch of code you have to step through line by line to see what it does. As this is incredibly annoying and inefficient, someone invented comments. We've covered these already, and there's a whole bunch of theory of when and how to comment, but to sum it up: comment often and clearly. It will save you time in the end. When the Tcl compiler sees a pound sign (#) at the beginning of a line, it ignores it. If you want to put a comment after a line of code, just enter a semicolon (;) first, which stands for "newline."
% # I'm going to set x equal to 4!
% set x 4 ;# There! Now the variable x contains the value 4!
4
%
Substitution
Tcl uses special characters to signal a substitution. We've already seen this when we used the $ sign to signal the value of a variable instead of the name. The backslash (\) allows reserved characters, like the dollar sign, to be used in strings. Any character with a backslash in front of it is not substituted. For example:
% set x 24 ;# Now the value of x is 24
24
% set y $x ;# Now the value of y is the value of x (which is 24)
24
% set z \$x ;# Now the value of z is literally "$x"
$x
%
That's basic substitution, not too tough. There is also something called 'command substitution' that lets you nest commands within each other. If you're not a programmer already, you may not be familiar with this concept, but it is fairly important. Since every command returns a result, you can nest commands inside one another, and use the result of one command as the input for the next command. You do this by surrounding the nested word in [brackets]. Say you had one variable, and you wanted the second to be equal to 10 times the first, how would you do this?
% set x 4
4
% set y [expr $x * 10] ;# This nests the expression 'expr $x * 10' within 'set y __'!
40
%
Tcl will compile the program so that whatever is on the innermost set of brackets is compiled first, on outwards. We could put the value of y to the screen and set x all in one step if we wanted:
% puts [set y [expr [set x 5] * 10 ] ] ;# note that we changed the value of x to be 5
50
While this is sort of neat, it's pretty awkward to read, so it's usually best to use nesting where it's needed and not for saving vertical space.
Quotes vs. Braces
When you need to group a bunch of things together, you have a choice between surrounding them in "quotation marks" or {braces}. Quotes allow substitutions, while brackets don't. Eh? Here's an example:
% set x 24 ;# the variable x contains the integer 24
24
% set y "I have $x marbles." ;# y is the string "I have [the value of x] marbles"
I have 24 marbles.
% set z {I have $x marbles.} ;# z is the string "I have [literally "$x"] marbles"
I have $x marbles.
%
Lists
One of Tcl's most powerful features is list manipulation. A list is basically a variable with multiple strings as variables. Those strings can be manipulated in a variety of ways, using commands the usually start with the letter 'l'.
% set My_List {one two three four}
4
% set Second_List {1 {2 3} 4 five}
4
%
When you create a list with set, it returns the number of items in that list. So why were there only 4 items in the second list? Because it counts {2 3} as one item. This means that lists can be nested in one another! You'll learn more about lists when you read about all the "l" commands in the next section.
Arrays
Arrays are basically indexed lists. The most common way to do this is numerically, but any string can be used as the pointer (the name that points to the object). You can usually think of an array as a table with two columns, the left being the pointers, the right being the values. Once again, the set command is used to initialize arrays. The syntax is: set variable(pointer) value.
% set x(0) 10 ;#This sets the value of the array x at position 0 to be 10
10
% set x(fred) 20 ;#now the array at position "fred" has the value 20
20
% set x(20) bob ;#the computer remembers that x(20) is "bob"
bob
% puts $x($x(fred)) ;#put the value of position 20 in the array
bob
So yes, arrays are fully nest-able as is most anything in Tcl. If you still aren't getting what the heck an array is, right now the array x looks kind of like this:
Index | Value
0 |
10 |
20 |
Bob |
Fred |
20 |
The left column represents the pointers that tell the computer where to look for a particular value (the right column). Arrays are dynamic, so you can always add new values and addresses (or kill them with unset). They tend to be used a lot with loops, as you can easily "step" through an array if the index is 0,1,2,etc.
While most of the operators in Tcl will be familiar, some (like equals) may seem strange unless you know C.
& or && |
AND (there's probably a difference...) |
| or || |
OR |
^ |
exclusive OR |
== |
equal (that's two = signs) |
!= |
not equal |
! |
NOT |
+, - |
add, subtract |
*, / |
multiply, divide |
% |
modulus operator (ex: 7 % 4 == 3) |
<, > |
less than, greater than |
<=, >= |
less than or equal, greater than or equal |
If/Then Else
Some of the critical parts to any programming language are the "if/then-else" set of statements. This is how you tell your computer to make decisions! The syntax for a simple "if" is: if {condition} {script}. Say you're writing a program that takes two pre-defined variables, we'll use "first" and "second", and puts the larger value into "biggest", here's one way to do it:
% set first 10
10
% set second 12
12
% if {$first > $second} {set biggest $first } ;# if 1st is greater than 2nd, then biggest gets the value of first
% if {$first <= $second} {set biggest $second} ;# if 1st is less than or equal to 2nd, then biggest gets second
12
%
It worked, but it sure is clunky. That's why there's the elseif addition! The true format for the if statement is: if {condition} {script} elseif {condition} {script} elseif {condition} {script} ... else {script}. The elseif is really just nesting if statements within one another. If the first statement is false, try the first elseif, if that is also false, try the second, and so on down to the end. If there is an else tacked on, and none of the if's are true, it does the else condition. So a much more efficient and clearer way to write the above code would be:
% if {$first > $second} {set biggest $first} else {set biggest $second}
12
%
Ta daa! This can be easily modified if you wanted to say "and if $first == $second then puts, 'they're equal!'"
% set first 12 ;#ok, I set them equal to see if this works
% if {$first > $second} {set biggest $first} elseif {$first < $second} {set biggest $second} else {puts "They're equal!"}
They're equal!
%
Loops
Like everything else in this section, loops will look familiar to programmers. If you're not one, then you're about to learn one of the most important aspects of coding! A loop basically tells the computer "repeat these set of instructions until some set of criteria are fulfilled." You could loop a script that asks for a user's name until something other than null (nothing) is entered, and very often you'll want to do something x times and loops are the way to do this. There are three types of loops that Tcl supports (that I know of): while, for, and foreach. We'll go over each in turn.
While loops are very simple, they merely say, "run this script until that condition is fulfilled." The syntax is while {condition} {script}. A great use for these is initializing arrays! So let's initialize an array, called Initialize_Me() (note that the open and closed parenthesis indicate an array) to all zeroes.
% set counter 0
0
% while {$counter < 5} {
> set Initialize_Me($counter) 0
> puts $counter
> puts $Initialize_Me($counter)
> incr counter
> }
[result]
%
Be careful with loops!!! It is very easy to forget to do something like increment the counter and just have it loop forever. Depending on what operating system and program you're using, it may not be easy to break out (for Windows95 users you may have to hit <ctrl><alt><delete> and use End Task on Console and on Packer (wish). Warning aside, loops are great! We just created an array with 5 positions, each of them containing a 0. You can use more or less any condition with the while loop, experiment and see what you can come up with.
"For" loops repeat the script while a certain syntax is met, and are very similar to while loops. The syntax is: for {initialization} {condition} {condition_modifier} {script}. These loops will normally take the form of something like "set counter to 0 (initialization) and while counter is less than 5 (condition) then increase it by 1 (condition_modifier) and set Initialize_Me($x) to 0 (script).
% for {set counter 0} {$counter < 5} {incr counter} {
> set Initialize_Me($counter) 0
> puts $counter
> }
[result]
%
This is often quicker and easier than a while loop, but they both have their respective uses. The final loop, "foreach" is a little different. The syntax is: foreach variable {value(s)} {script}. Foreach tells the computer, "run the script with variable equal to the first value, again with it equal to the second, and so on until there are no more values." We can run the same process as the last two loops again:
% foreach counter {0 1 2 3 4} {
> set Initialize_Me($counter) 0
> puts $counter
> }
[result]
%
That's it for loops! Chances are you'll find your favorite and stick with that one most of the time, but there are situations where it's good to remember all three.
Procedures
Now we're into some really neat stuff. Procedures are basically mini-programs that you use inside your main program. For example: if you've created a program that counts the number of words in a document anytime you press some button, chances are you'll have a procedure named Count_Words that does the actual counting. Then you'll make a widget for some button that says to the computer, "make me a button with the words 'Press me!' on it that runs Count_Words." Procedures are created using the proc command, which has the syntax: proc procedure_name {argument(s)} {body return return_value}. Let's try one out:
% proc MyFirstProcedure {first_argument second_argument third_argument} {
> set x [expr $first_argument + $second_argument]
> set y [expr $x * $third_argument]
> return $y
> }
%
If you can't see them, there are less-than signs on at the beginning of the middle four lines. Were you surprised when these popped up? Tcl is smart enough to realize that you're in the middle of a set (it recognizes that you haven't finished your {} set), so it signals you with a change in prompt. So what does our procedure do? Well, it takes in three arguments, which means that when you run it you'll type in MyFirstProcedure firstValue secondValue thirdValue. It will add the first two, and store the result in a temporary variable called x. A temporary variable only exists while the procedure is running, so if you tried to use $x outside the procedure, the computer wouldn't know what you're talking about. The value of x is multiplied by the third value, and the result is assigned to y. The procedure then returns the value of y, and exits. So let's run it!
% MyFirstProcedure 1 2 3
9
%
Success! See, procedures are easy! The only thing you might have to worry about are what are called "global variables." Since procedures operate using only temporary variables by default, if you want your procedure to be able to "see" a variable in the rest of your program, you have to put the line global variable_name(s) as the first line of your program. It's best to avoid these where possible, just pass the values using arguments, but if you need them, here's an example (if you don't understand what's going on, try it with and without the "global x" line):
% set x 24
24
% proc Global_Variable {y z} {
> global x
> set w [expr $y * $z + $x]
> return $w
> }
% Global_Variable 2 3
30
%
Ok, you've got the knowledge you need, so pick up a few commands and start scripting!
next page
contents
previous page
Copyright 1998 by Chris Palmer
Mail all comments to: Ardenstone@Ardenstone.com
Visit the rest of my Senior Seminar
or my homepage.