Version 34 of Tcl cheat sheet

Updated 2005-02-03 20:15:48

New in Tcl? Coming from another language? Read on.

This could be fun. I learned almost all of my programming with PHP, and a little bit of Perl. This sheet [L1 ] helped me an awful lot when I tried to learn Perl, so a Tcl cheat sheet may be awfully useful to someone else. Feel free to add other languages.

How about we get the Tcl stuff correct before adding other languages? Roy Terry, 17Jan2003

The following items seem to be referring specifically to use of the languages within a CGI context, rather than as individual characteristics of the languages themselves.


How do you name files:

PHP: file.php3

PERL: file.cgi

TCL: file.tcl

[Well, technically, the above isn't right, at least for Tcl and Perl. Neither Tcl nor Perl require you to use the ".???" extensions on the files. Some (many? most?) web servers might require one to have an extension on an executable. But even then, one can call Tcl cgi scripts file.tcl without a problem - Tcl wouldn't even care if you called the file "file.php3"...


How do you provide a CGI script to the server:

PHP: scripts embedded within <?php..?> tags on the HTML page itself.

PERL: whole file is script

TCL: whole file is script (unless you use mod_dtcl in Apache 1.3.x or mod_tcl/rivet in Apache 2.x (or likely some other options; there everything is like PHP)


How do you produce output for the user

PHP: can mix raw HTML and PHP

PERL: the cgi script must print all output, whether HTML or plain text

TCL: must print all output (unless you use mod_dtcl in Apache 1.3.x or mod_tcl/rivet in Apache 2.x, there everything is like PHP)


Is there any specific magic needed when writing the specific page/sript?

PHP: no requirements for first line inside the embedding tags

PERL: first line is #!/usr/local/bin/perl or any other path to your Perl interpreter (but is that a requirement?)

TCL: first line can be #!/usr/local/bin/tclsh or any other path to your Tcl interpreter (but that is absolutely irrelevant if you are using Windows). See exec magic for the recommended way to start a Tcl file if you want it to behave like an app on *nix systems.


What type of permissions does the code need?

PHP: since the code is not an independant executable file, but just tags within an HTML page, no extra permissions are needed

PERL: On systems which have such concepts, to run the code, you must make the code an executable file

TCL: On systems which have such concepts, to run the code, you must make the code an executable file


How do you make the code active?

PHP: chmod 644 file.php3 (set script file's permission so it is readable)

PERL: chmod a+x file.cgi (set script file's permission so it is executable)

TCL: chmod a+x file.tcl (set script file's permission so it is executable)


How do you produce output in the language?

PHP: echo "stuff\n";

PERL: print "stuff\n"; OR printf "am am using %s printing conventions!", 'C';

TCL: puts stuff OR puts "some stuff" OR puts {some stuff}. It may be useful here to point out that Tcl adds a trailing newline by default. To disable this behaviour use the -nonewline option to puts.


What is the format for using variables?

PHP: All variables $var

PERL: $var is a scalar variable; @var is an array variable, %var is a hash variable.

TCL: var refers to the name of a variable which is needed every time you want to modify its contents (write to the variable); or $var referes to the content of the variable to be used when you want to read the variable . See set


If variable types are supported, how does one reference the differing types?

PHP: $var always means one thing

PERL: $var, @var, %var, var are different things!

TCL: since all variables var have a $ in front, $var always means the same thing. But beware: var could be scalar or an array variable and has to be used according to that!


What kind of collection data type does the language support?

PHP: $var = array(1,2,3);

PERL: @var = (1,2,3); or %var = ("apple"=>'value for apple', "potato"=>'val2', "carrot"=>'carrot is red');

TCL: well, there are lists which work very fine, plus there are arrays (which are called hashes in some other languages), see below

 set var "1 2 3"  '''OR'''  set var [ list 1 2 3 ] while the latter is preferred especially in cases where the contents are not as simple as "1 2 3", but may contain spaces, return values from functions and so on. Only the list command helps you to correctly use quoting.

and arrays...

 array set var "key1 value1 key2 value2 key3 value3"

PHP: "numeric" arrays and "associative" arrays

PERL: "arrays" and "hashes"

TCL: "lists" and associative "arrays" - of course the associative arrays can have numbers as indexes.

(NEM and we now have dicts)


How do you reference a specific member of a data collection type?

PHP: $var[1] is second element of array $var

PERL: $var[1] is second element of array @var; $var{1} is the data for key value 1 for hash %var

TCL: [ lindex $var 1 ] is second element of $var and $var(1) is the data file key value 1. [dict get $var 1] will in Tcl8.5 return the value associated with 1 in the dict $var.


How do you determine the size of a collection data type?

PHP: count($var) is number of elements in array $var

PERL: scalar(@var) is number of elements in array @var; scalar(keys %var) is the number of elements in the hash %var

TCL: [ llength $var ] is length of list, and [array size var] is number of elements in array. [dict size $var] is the number of mappings in a dictionary.


How do you display all the elements of the collection data type?

PHP: for ($i=0; $i<count($var); $i++) echo $var[$i];

PERL: foreach $thing (@var) { print $thing; }; or just print @var; for hashes: print map {"$_->$var{$_},"} keys %var;

TCL: for { set i 0 } {$i < [ llength $var ] } { incr i } { puts [ lindex $var $i ] }

NEM This Tcl example would be far better written as: foreach thing $var { puts $thing }

RT And this is better yet: join $var, or join $var <br>, etc.

Working through an array works like this:

 foreach index [array names var] {
    puts $var($index)
 } ;# foreach

Note however that the Tcl foreach has at least one differing characteristic from Perl's foreach.

In perl, one has to note this behavior -- the index variable of a Perl foreach loop is a reference to the elements of the array, NOT a copy of the element!

 @x = (1, 2, 3);                # Create a 3 element list/array
 foreach $i (@x) {
        print $i++ . "\n";
 }
 # At this point, array contains 2, 3, 4!

In Tcl, using a similar program structure

 set x [list 1 2 3]
 foreach i $x {
        puts "$i"
        incr i
 }

At the end of the loop, the x list members have not changed their values. Certainly one can construct code that will update it. This note is just to let someone trying to convert code from one language to another be aware of a difference in the behavior.

For dictionaries, you can just print the dictionary. :^) However, that's not always the neatest way of doing it. Here's a neater way.

 dict for {key val} $theDictVar {
    puts "$key => $val"
 }

As with arrays, modifying key or val in the body of the [dict for] won't affect the dictionary. In fact, you can even update the dictionary in the variable while the [dict for] is progressing and the loop will not be affected at all.


How do you create a string from an array ?

[Huh? Why would you _want_ to do this? Please be a bit more specific about what it is that you are trying to accomplish, so that comperable functionality can be coded. ]

PHP: join(":",array(1,2,3))

PERL: join ":", 1,2,3;

TCL: join [ list 1 2 3 ] : (yeah, yeah, you can wrap the colon in quotes if you're queasy)


How are the collection data types treated as objects?

Er... what is a "type"? ;-) If you like objects you could use incr Tcl or stooop [Again, please be a bit more specific about _what_ it is you are going for here so that comparable information can be supplied.]

PHP: associative arrays are arrays

PERL: associative arrays are their own type

TCL: Lists and dicts are values. Arrays are collections of variables. The array get and array set commands make a value out of the data in an array and vice versa.


How do you create an array?

PHP: $var = array(1=>"ho","hi"=>4);

PERL: %var = (1=>"ho","hi"=>4);

TCL: array set var [list 1 ho hi 4] or alternatively: set var(1) ho; set var(hi) 4 No explicit creation is necessary.


Access value of single array element 'ho'

PHP: $var['ho']

PERL: $var{ho} (if var is a hash (%var) - if var is an array (@var) then its existance does not influence %var; for constants with no white space, quotes not needed)

TCL: $var(ho) (for constants with no white space, quotes not needed)


How do you iterate through a hash?

PHP: while (list($k,$v) = each $var)) {...}

PERL: while (($k,$v) = each %var) {...}

TCL: foreach { key value } [ array get var ] {...}

Copying the contents of an array A to an array B would in Tcl be

  array set B [array get A]

if that is what was intended.


to be continued...

Roy Terry, 17Jan2003 - say this looks helpful. On your next pass can you be more specific on 1) What each section is trying to demonstrate, and 2) your questions about Tcl. "??? - confusing" doesn't give folks a good idea of what additional info you need. One obvious correction: Tcl uses parens, not square brackets, to index arrays. Further more the single quote has absolutely no special meaning in Tcl, it does not quote things and it will not be removed by the parser; so best to avoid it. Now I see something else: In Tcl variables can be either an array or a string value and that's determined by usage.

LES: It's not Tcl that confuses me. It's the PHP and Perl examples that confused me, so I am not sure how to translate them into Tcl. For example: instead of saying $var['ho'] is element indexed by 'ho' , I'd rather say "ho" is element indexed by $var['1']. Do I make myself clear? RT - no I don't think you do. Take a look at the array access segment now. I think it helps to put the "operation" at the top of the section and then just list the code sample.

VK: I fixed many Perl samples: there was an error in one place and misunderstanding in another: in perl you can have $var @var %var - those are 3 different concept - a scalar, an array and hash. It is wrong to think that once 'var' is a hash, you can't use it as an array.

glennj (updated some items above)


Category Language