Tcl (originally from "Tool Command Language", but nonetheless conventionally rendered as "Tcl" rather than "TCL"; and pronounced like "tickle") is a scripting language created by John Ousterhout that is generally thought to be easy to learn, but powerful in the right hands. It is most commonly used for rapid prototyping, scripted applications, GUIs and testing. Tcl's features include:
While Tcl itself does not provide an object oriented framework, the language itself can be extended to provide new features as required. Indeed, many C extensions have been written to provide OO functionality, including the XOTcl and incr Tcl packages. Other OO extensions, including Snit, are written entirely in Tcl.
The most popular Tcl extension is the Tk toolkit, which provides a graphical user interface library for a variety of operating systems. Another popular extension is Expect, which allows automated driving of terminal-based programs (such as passwd, ftp, telnet and command driven shells).
A simple working example, demonstrating event-based handling of a socket, follows.
#!/bin/sh
# next line restarts using tclsh in path \
exec tclsh $0 ${1+"$@"}
# echo server that can handle multiple
# simultaneous connections.
proc newConnection { sock addr port } {
# client connections will be handled in
# line-buffered, non-blocking mode
fconfigure $sock -blocking no -buffering line
# call handleData when socket is readable
fileevent $sock readable [ list handleData $sock ]
}
proc handleData { sock } {
puts $sock [ gets $sock ]
if { [ eof $sock ] } {
close $sock
}
}
# handle all connections to port given
# as argument when server was invoked
# by calling newConnection
set port [ lindex $argv 0 ]
socket -server newConnection $port
# enter the event loop by waiting
# on a dummy variable that is otherwise
# unused.
vwait forever
Another example using Tk (from A simple A/D clock) and timer events, a digital clock in three lines of code:
proc every {ms body} {eval $body; after $ms [info level 0]}
pack [label .clock -textvar time]
every 1000 {set ::time [clock format [clock sec] -format %H:%M:%S]} ;# RS
Explainer: the first line defines a command, "every", which re-schedules an action ('body') every 'ms' milliseconds; the second creates a label whose content is bound to the variable 'time'; the third line arranges so that the variable 'time' is updated to formatted local time every second.