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 [http://www.cs.tufts.edu/g/20/notes/php_perl.php] 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 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/script?''' '''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. The first line magic is only not required if one is on Windows systems. Otherwise, it is required if one wants the script file mentioned to automatically execute with the language interpreter. If the user is willing to supply the interpreter along with the script name (aka '''perl something''' or '''tclsh tkconsole''', etc.), then the script does not require the first magic line. ---- '''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 "I am using %s printing conventions!", 'C'; '''Tcl:''' puts stuff '''OR''' puts "some stuff" '''OR''' set other {some string of information} puts "some $other stuff" '''OR''' puts {some stuff} '''OR''' puts [format "I am using %s printing conventions!" C] 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. ====== puts -nonewline "some stuff" ====== Also, note that there is no comma between arguments in Tcl, whereas in Perl, there are. Also, while Tcl permits a trailing semicolon (;), it is only required when used as a statement seperator. ---- '''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''' refers to the content of the variable to be used when you want to read the variable . See [set] for more details. '''var(index)''' refers to an array variable. ---- '''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 variable types (string, array, hash)! '''Tcl:''' since all variables ''var'' have a $ in front, $var always means the same thing. But beware: var could be a 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 [dict]s) ---- '''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 the second element of list $var and $var(1) is the data for array key value 1. [[dict get $var 1]] returns 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$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
]], 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; # I don't know PHP, but suspect that before the semicolon here, you need to add a , "\n" to produce a newline. '''Tcl:''' join [[ list 1 2 3 ]] : (yeah, yeah, you can wrap the colon in quotes if you're queasy) [[Um? A list isn't an array. First convert array to list with '''array get''' e.g.: join [[ array get env ]] : Also note that parray prints a formatted output of "array(xx) = value" e.g.: parray env ]] However, neither of these results in the same output as the first two. The PHP and Perl statements create an array containing the values 1, 2, and 3, then retrieve the values of the array, and outputs those values separated by a colon. The Tcl array and dict need another round of examples to get something a bit closer to the effort. As for the question of why one would want to do this - why, to produce a [csv] type record of the values in the array, perhaps? ---- '''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. [TJK] - The [Snit] package (found in [tcllib]) is a pure-tcl object framework that uses type definition as its model. If you need "types" that look like objects then use [Snit]. ---- '''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']] [TJK] or $var[[ho]] (if constant with no white space) '''Perl:''' $var{ho} (if var is a hash (%var) - if var is an array (@var) then its existence 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:''' foreach ($var as $k => $v) {...} [TJK] or foreach( array_keys($var) as $key ) {...} '''Perl:''' while (($k,$v) = each %var) {...} '''Tcl:''' foreach { key value } [[ array get var ]] {...} '''OR''' set srchId [array startsearch var];set srchId [array nextelement var $srchId]; array donesearch var $srchId 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 concepts - 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] |% !!!!!!