Tcl Introduction
A Simplest Example |
Basic | Contorl | Procedure | Object
Tcl (Tool Command Language) is created by Dr. John Ousterhout in 1989. Tcl is designed as a small language that is easy to be embedded and extended. It is a scripting language with simple and elegant syntax rules. Tcl can easily glue components together. And it is portable on main platforms such as Windows, Unix, and Macintosh. Programmers are more productive by using the Tcl and their extensions for rapid software development.
Many enterprises are beginning to realize the power of Tcl and use Tcl for their applications. For example, AOL and CNET had applied Tcl for their online services; Cisco and Nortal applied Tcl on their network software testing and management; NationalBank used Tcl for its financial system management. Lucnet Technology used Tcl for EDA applications.
Questions:
- What language is used for the implementation of Alfred in Pixar?
A Simplest Example
pack [button .b -text "Hello" -command {puts "Hello World!"}]
This simplest Tk example shows a Hello button on the Main window. When you click the button the console window will display the string "Hello World!" on the console.
button command creates an instance .b button called .hello. -text string shows the button title. -command string is the command responsed to the button's action. pack command layouts the button on the window.
This example demonstrates geometry management, font management, and callbacks.
Basic
Tcl is a typeless scripting language. Its basic syntax and structure looks like.
command argument1 argument2 ...
where command is a basic function or a defined procedure in the Tcl interpreter. The arguments are separeted by the white space. A newline or semicolon is the the termination of a command. Each command will return a string or a null value. The arguments are string value. The basic operating mechanisms of Tcl are grouping, substitution, and dispatch.
-
Grouping
square brackets [] represent the nested command. The command is executed and return a value. [clock seconds]
curly braces {} group words into a single argument without interpreting the words in the braces. set words {the time is [clock seconds]}
double quotation "" marks group words as a single argument and interprets command and substitution inside. set words "the time is [clock seconds]"
-
Substitution
$variable dollar sign $ evals variable and get its value return. set variable "variable value"
\ backslash is used to quote special character such as \, ", and $. \n returens the newline. \t returns a tab. \{, \}, \$ are quote for these special character. puts "The \{first\} line.\nthis is the second line."
#comment is a comment in the beginning of a line or after the semicolon. # comment here please
-
Dispatch
After grouping and substitution, Tcl
command calls a build-in function or procedure to
execute this command. This is the procedure of
dispatch. In the Following paragraphs we are going
to describe some building commands in the Tcl.
Control
-
if boolean body_true else
body_false
it is a conditional command.
If the value of boolean_expression is true then
execute body_true, otherwise execute
body_false.
if {$variable < 0} {
set retval -1
} elseif ($variable > 0) {
set retval +1
} else {
set retval 0
}
-
while boolean
body
it evaluates the boolean if it
is true execute the body and repeates the
procedure, otherwise the while command
terminate.
set count 7
while {$count > 0} {
puts 2*$count; incr count -1
}
-
for
initial boolean increment body
its initial_setting
initializes the loop. If the second argument
boolean_expression returns non zero value the loop
continues. The third argument increment is executed
{after} the execution of the body_for
for {set count 0 } {$count < 7} {incr count 1} {
puts 2*$count
}
-
braek, continue, and
return
break command exits the loop. continue command executes next iteration. return command returns from a procedure
Procedure
-
proc name
arguments body
it provides a method to define a sequence of commands. The variables in the procedure have a local scope. The first argument is the procedure name. The arguments is the list of argument name. The body is the command sequence of the procedure. The return command can be used inside the body to returen a value.
proc distance {a, b, x, y} {
return sqrt(($x-$a)*($x-$a) + ($y-$b)*($y-$b)
}
-
global variable
...
global scope is the top level
scope. After a variable is defined by global it is
visible in the global scope. It is not necessary to
define a global variable in the global scope. You
need to declare the global variable in every procs
you use it. Its replacment is ::variable that puts
prefix :: on a global variable.
global variable1 variable2
-
Namespace
namespaces speccificate new
scopes for global variables and procedures. By
using namespaces programmer can organize the large
Tcl programs. Neatware strongly suggests you use
the namespaces for your Tcl project although it may
be little bit complexity to use with the callback
commands. Namespaces have the following
syntax:
namespace eval name {
variable var initvalue
namespace export proc1 proc2 ...
}
proc name::proc1 {args} {
variable var
# commands ...
}
...
proc name::procn {args} {
# commands ...
}
name is the namespace name that is declared by namespace eval. variable declares the var variable and its init value. namespace export declares the procedure names that will be available to call. The proc statements define the procedures. You may call a procedure by name::procn args. You need to declare a variable var when you want to use it in a procedure.
The namespaces may be nested. You may save to write namespace header in each calls with namespace import command. The callback commands such as after are evaluated later. Their default scopes are global. By using the namespace code prefix in front of the callback commands you can execute the callback command later in current scope. Namespace has the same
stack level like procedure. You may access all the variables with uplevel or upvar.
Object
-
String
String is a primitive object of
Snaml. It consists of any characters. Some
characters may have special meaning for a string in
the context.
-
String
Construction
(i) 'append v s1 s2 ...' command
concatenates s1 s2 ... onto the variable v;
(ii) the 'join LIST
s' command joins the elements of
LIST together and distinguishes them with a
string s. The default string s is a
space.
set v "one " ;# v is "one two three"
append v "two " "threr "
set l {a {b c} d} ;# l is "a::{b c}::d"
join l "::"
-
String
Access
(i) 'string length
STRING'
command returns the number of characters of the
STRING; (ii) 'string range STRING i j' command
returns the substring of the STRING from i to
j; (iii) to get an element, 'string
index STRING
i' returns the character in the
position i. The starting position of a string
is 0; (iv) to find the occurrence of a string,
'string first STRING1
STRING2' command returns the
first occurrence of STRING1 in the STRING2; (v)
the 'string last
STRING1 STRING2' command finds
the last occurrence.
set s "abc defe"
set n [string length $s] ;# n is 8
set r [string range $s 1 5] ;# r is "bc de"
set i [string index $s 0] ;# i is "a"
set f [string first "ef" $s] ;# f is 5
set t [string last "e" $s] ;# t is 7
-
String
Operation
(i) 'string compare
STRING1
STRING2' compares two strings.
It returens 0 if they are equal, or -1 if
STRING1 is less than the STRING2, otherwise +1;
(ii) to find a string in a pattern,
'string match PATTERN
STRING' command completes
pattern matching. PATTERN may be the
combination of characters and the special
matching characters where * for any characters,
? for any single character, and [xyz] for one
of a character in the [ ]. If STRING matches
the PATTERN it returns 1, otherwise returns 0.
(iii) 'string tolower
STRING' and 'string
toupper
STRING' will convert the STRING
to lower and upper case respectively. Examples
of string compare are:
set s "abc "
set r [string compare $s "abc"]
if {$r == 0} {
_quote "s == 'abc'"
} elseif {$r == -1} {
_quote "s < 'abc'"
} else {
_quote "s > 'abc'"
}
string match example:
if {[string match {a?[xyz]} $s] == 0} {
_quote "matched"
}
string conversion
example:
set l [string tolower $s]
set u [string toupper $s]
-
String
Format
'format STRING v1 v2
...' command is similar to
printf() function of C. It returns a formatting
string. STRING is the format specification.
v1, v2 ... are
corresponding values.)
set s "32"
set d [format "%2d" $s]
-
List
List is a useful type to represent
document structure. It is a general expression of
tree structure.
-
List
Construction
(i) 'list a1 a2 ...' command
constructs a list from its arguments a1, a2,
... . The curly brace { } also represents a
list; (ii) 'lappend
LIST a1 a2 ...' command appends
arguments a1, a2, ... to the the end of the
LIST as elements; (iii) to merger lists,
'concat LIST1 LIST2
...' joins the elements in
LIST1, LIST2, ... together to form a new list;
finally, (iv) 'split
STRING c' command returns a list
that splits the STRING with characters
c.
set lx [list a b c {d e}]
set ly [lappend $l {g h}]
set lxy [concat $lx $ly]
set s "a, b, c"
set l [split $s ","]
-
List
Access
(i) 'llength LIST' returns the
number of elements in the LIST; (ii) to get a
sub-list, 'lrange LIST
i j' command returns elements of
LIST from i to j; finally, (iii) 'lindex
LIST i'
returns the ith element of the LIST.
set l {a b {c d}}
set n [llength $l] ;# n is 3
set e [lrange $l 0 1] ;# e is {a b}
set i [lindex $l 2] ;# i is {c d}
-
List
Operation
'lsearch option LIST v' returns the
index of LIST that matches the value v in one
of an option or return -1 if no value is found.
-glob, -exact, and -regexp are possible option
values. The default option value is -glob.
(i) to add a new
element into a list, 'linsert LIST i a1 a2 ...' command
inserts elements a1, a2, ... before the index i
of the list LIST. It returns the new list; (ii)
to update elements, 'lreplace LIST i j a1 a2 ...'
command replaces elements from i to j in LIST
by elements a1, a2, ... and returns the new
list; (iii) 'lsort
option LIST' sorts elements in
LIST according to the options value (-ascii,
-integer, -real, -dictionary, -increasing,
-decreasing, -command, -index i). The default
options are '-ascii -increasing'. It
returns the new list.
set l {a b {c d}}
set n [lsearch -exact "b"] ;# n is 1
set v [linsert $l 1 "f"] ;# v is {a f b {c d}}
set u [lreplace $l 0 0 "g"] ;# u is {g f b {c d}}
set s [lsort -increasing $l] ;# s is {b {c d} f g}
-
Array
In
Tcl an array
is same as the
array
of Tcl. It is
more
like a map rather
than
traditional array
in
C. It is a collection
of key/value pairs.
The key is the
index
and the value
is the element of
an
array. An element
of array 'a'
with index 'key'
is represented
as
a(key). Its value
is $a(key). An
array is implemented
as a hash
table.
-
Array
Construction
'array names ARRAY [PATTERN]'
command returns the list of ARRAY keys that
match the PATTERN. If no PATTERN item it
returns the list of all the keys of the
ARRAY.
set a(x) "abc"
set a(y) "def"
set l [array names a] ;# l is {x y}
-
Array
Access
(i) 'array exists
ARRAY' returns
1 if ARRAY is an array variable, otherwise it
returns 0; (ii) to get the number of elements
of ARRAY, 'array size
ARRAY' returns this
value.
if {[array exists a] == 1} {
_quote "a is an array"
set n [array size a]
} else {
_quote "a is not an array"
set n 0
}
-
Array
Operation
(i) 'array get
ARRAY
[PATTERN]' returns a key/value
pair list. PATTERN is used for matching keys.
Without PATTERN 'array get' command
will return all the pairs; (ii) 'array
set ARRAY
LIST' command sets ARRAY with
the LIST in the key/value form.
set a(x) "abc"
set a(y) "def"
set l [array get a] ;# l is a list {x abc y def}
array set b $l ;# b is an array same as a
-
Regexp
Regular Expression (Regexp)
is a powerful tool for text processing. It provides
pattern matching for string data. Much of following
description of regular expressions is copied
verbatim from Henry Spencer's manual entry.
Henry Spencer makes a very efficient implementation
of the regular expression.
A regular expression is zero
or more branches, separated by ``|''. It
matches anything that matches one of the branches.
A branch is zero or more pieces,
concatenated. It matches a match for the first,
followed by a match for the second, etc. A
piece is an atom possibly followed by
``*'', ``+'', or ``?''. An
atom followed by ``*'' matches a sequence
of 0 or more matches of the atom. An atom followed
by ``+'' matches a sequence of 1 or more
matches of the atom. An atom followed by
``?'' matches a match of the atom, or the
null string.
An atom is a regular
expression in parentheses (matching a match for the
regular expression), a range (see below),
``.'' (matching any single character),
``^'' (matching the null string at the
beginning of the input string), ``$''
(matching the null string at the end of the input
string), a ``\'' followed by a single
character (matching that character), or a single
character with no other significance (matching that
character).
A range is a sequence of
characters enclosed in ``[]''. It normally
matches any single character from the sequence. If
the sequence begins with ``^'', it matches
any single character not from the rest of the
sequence. If two characters in the sequence are
separated by ``-'', this is shorthand for
the full list of ASCII characters between them
(e.g. ``[0-9]'' matches any decimal digit).
To include a literal ``]'' in the sequence,
make it the first character (following a possible
``^''). To include a literal ``-'',
make it the first or last character.
-
regexp
The regexp command has
the syntax, 'regexp
[switches] REGEXP STRING [matchvar]
[submatchvar ...]'.
It returns 1 if part of or
all STRING matches regular expression REGEXP,
otherwise it returns 0. The
'matchvar' stores the string that
matched entire REGEXP.
'submatchvar' stores the string
that matched the leftmost parenthesized
subexpression within REGEXP. The optional
switches may have value -nocase, -indices, and
--. Here, '-nocase' treates
upper-case characters in STRING as lower- case.
'-indices' specifies that the
matchvar contains a pair of numbers that is the
position of matched substring in the STRING,
otherwise matchvar stores the matched
substring. Finally, '--' marks
the end of the switches.
regexp (ab|a)(b*)c "abc" match submatch1 submatch2
where match has the value
"abc"; submatch1 has the value
"ab"; and submatch2 has the empty
value.
-
regsub
The regsub command
substitutes string according to the matching of
regular expression. Its syntax is:
regsub [switches] REGEXP
STRING SUBSTITUTE VARIABLE
If there is no match in
the STRING for REGEXP, regsub command returns
0, otherwise it returns the number of matches.
In addition, regsub replaces the matched
REGEXP in the STRING with the SUBSTITUTE. The
new replaced string is stored in the VARIABLE.
The '&' and '\1' to
'\9' characters are special characters
during the substitution. The '&' is
replaced by the matched string. \1 to \9 are
the first and nine matched substrings. The
'switches' may be the value -all,
-nocase, or --. '-all', option
will replace all the occurrences of the REGEXP
pattern. Only first occurrence is replaced in
default. '-nocase' means case
insensitive when makes a match.
'--' is the end of the
switches.
regsub -all {%([0-9a-hA-H][0-9a-hA-H]])} \\
$url {[format %c 0x\1]} newurl
This is an example in CGI
program where URL with special characters is
encoded with a hexadecimal code %xx. Then the
format command will decode the
corresponding character with hexadecimal
code.
-
File
File commands are divided into directory and file operations.
-
Directory
Status
(i) 'file dirname
name' returns
a directory name in a path. If name is a
relative file name and only contains one path
element, then returns ``.'' (or
``:'' on the Macintosh). If name refers
to a root directory, then the root directory is
returned. (ii) 'file tail name' returns the name
after the last directory separator. If name
contains no separators then returns name itself
(iii) 'file isdirectory name' returns 1 if file
name is a directory, otherwise returns 0. (iv)
'file mkdir dir
...' creates one or more
directories. For each pathname dir specified,
this command will create all non-existing
parent directories as well as dir itself. If a
directory exists, then no action is taken and
no error is returned. Trying to overwrite an
existing file with a directory will result in
an error. dir arguments are processed in the
order specified, halting at the first error, if
any.
file dirname ~/src/foo.c # returns ~/src
file tail ~/src/foo.c # returns foo.c
file mkdir src # create src directory
-
File
Status
(i) 'file size name' returns the
file size;
(ii) 'file atime name' returns a
decimal string giving the time at which file
name was last accessed. The time is measured in
the standard POSIX fashion as seconds from a
fixed starting time (often January 1, 1970). If
the file doesn't exist or its access time
cannot be queried then an error is
generated;
(iii) 'file stat name varname'
invokes the stat kernel call on name, and uses
the variable given by varname to hold
information returned from the kernel call.
varname is treated as an array variable, and
the following elements of that variable are
set: atime, ctime, dev, gid, ino, mode, mtime,
nlink, size, type, uid. Each element except
type is a decimal string with the value of the
corresponding field from the stat return
structure; see the manual entry for stat for
details on the meanings of the values. The type
element gives the type of the file in the same
form returned by the command file type. This
command returns an empty string;
(iv) 'file attributes name [option]'
this subcommand returns a list of the platform
specific flags and their values. The 'file
attributes name [option value ...] sets one or
more of the values. The values are as
follows:
On Unix, -group gets or sets the
group name for the file. A group id can be
given to the command, but it returns a group
name. -owner gets or sets the user name of the
owner of the file. The command returns the
owner name, but the numerical id can be passed
when setting the owner. -permissions sets or
retrieves the octal code that chmod(1) uses.
This command does not support the symbolic
attributes for chmod(1) at this time.
On Windows, -archive gives the
value or sets or clears the archive attribute
of the file. -hidden gives the value or sets or
clears the hidden attribute of the file.
-longname will expand each path element to its
long version. This attribute cannot be set.
-readonly gives the value or sets or clears the
readonly attribute of the file. -shortname
gives a string where every path element is
replaced with its short (8.3) version of the
name. This attribute cannot be set. -system
gives or sets or clears the value of the system
attribute of the file.
On Macintosh, -creator
gives or sets the Finder creator type of the
file. -hidden gives or sets or clears the
hidden attribute of the file. -readonly gives
or sets or clears the readonly attribute of the
file. Note that directories can only be locked
if File Sharing is turned on. -type gives or
sets the Finder file type for the file.
set s [file atime filename]
set len [file size filename]
-
File
Operation
(i) 'file copy
source target'
copies source file to the target file or
directory; (ii) 'file delete pathname ...' remove
files and directories; (iii) 'file
rename source
target' rename source file name
to the target; (iv) 'file join name [name ...]'
takes one or more file names and combines them,
using the correct path separator for the
current platform; (v) 'file split name' returns a list
whose elements are the path components in name.
The first element of the list will have the
same path type as name. All other elements will
be relative.
file copy src.sal dest.sal
-
Channel
A channel maybe either a file or a
pipeline processes. You may create, open,
read/write, and close a channel.
-
Channel Creation and Close
(i) 'open name [access]
[permission]' returns a channel
id. The 'name' maybe a file name or a
pipeline specification. The 'access'
maybe fopen like format or POSIX format. The
'permission' is the permission access
on the new file. Its default value is 0666 that
permits read/write for anyone. (ii)
'close
cid' will close the channel cid.
(iii) 'flush
cid' writes the content of
buffer to the channel.
FOPEN Access Format
r read
r+ read & write
w write; file exists truncate, otherwis create
w+ write & read; file exists truncate, otherwise create
a write; append
a+ read & write; append
POSIX Access Format
RDONLY read
WRONLY write
RDWR read & write
APPEND append
CREAT create if file not exists
TRUNC truncate
use with catch example:
if [catch {open filename "w+"} fid] {
puts "open file error!"
} else {
# processing
close $fid
}
-
Channel
Status
(i) 'seek cid offset [org]'
sets the current position to offset from the
org. org may have the value start, current, or
end. (ii) 'tell
cid' returns current position of
the channel (iii) 'eof cid' if it is the end of
file.
set pos [seek cid 256 start]
-
Channel
Access
(i) 'read cid [nbytes]' reads
nbytes or entire data from cid. It returns the
reading data. (ii) 'write cid string' writes a
string to the cid.
set data [read cid 256]
|