Example fragments of Tcl source
Table of contents
Among the most commonly-asked questions in comp.lang.tcl are, "How
do I get fileevent to work?", "How do I communicate between two
processes?", "Can I use named pipes with Tcl?" and "How do I show
the results of a process in a text widget?" (approximately; usually
the questioners don't realize what they're asking sufficiently well
to articulate them this way). Andreas Kupries answered all four of
these with a single
newsgroup
posting. He also offered an
alternative version
which uses
sockets in place of pipes. I wrote a
tutorial
form
covering much the same territory for SunWorld Online.
[refer to other IPC] [cross-reference widget use]
One question that often appears is, "How can I tell if
a string represents a number (in the sense that '12' does,
but 'This is a sentence.' does not)?" One
thread
generated several examples.
Bob Techentin offers a concise example of a
flashing
button. Nat Pryce explains
the
principle
in detail.
Donal K. Fellows'
font
previewer is far more than just
a simple example.
Steffen Traeger
has made available a small application,
hpupdate,
which automatically updates his homepage sources. It implements
"some basic features of a FTP Client like list, delete,
upload, compare files/directories."
[Explain
Sunlab's
example of dynamic loading.]
Victor Wagner nicely
illustrates
how easy it is to conduct HTTP business, even without the newer commands
introduced with version X.X.
How do I obtain the IP address of my host? First understand that
most of
the
difficulty in this topic is inherent to IP, and not
specific to Tcl. Donal Fellows offered a
fragment
which almost
completely answers the question. Heribert Dahms
"robustifies"
it a bit, while
A. N. Martin
and
Chris Nelson
hint
at the complexities Windows introduces [explain DHCP not a Win* sin].
Perhaps I'll make the time someday to synthesize this into the correct
dozen lines of Tcl source ...
This
little example
is portable, of course; it's handy for
automating mail from a Unix, Win*, MacOS, or
OpenVMS
application. Maybe I'll comment it someday.
Andreas Kupries points to
a
handful of possibilities for initiating e-mail with Tcl.
D. J. Hagberg's
ezsmtp package
is a good example.
Rildo Pragana automates the
operation
of splitting a large
file and e-mailing its segments.
tkmsmail
connects to MAPI services--that is, Exchange.
Gareth Owen's
offering
is particularly careful about error-handling and platform dependencies.
[... later ...]
"How do I manipulate both the output of an exec
-ed program,
and its return value?" Here's a Unix-oriented example that's easy to
generalize for Win*, OpenVMS, ...:
Create an executable /tmp/program
derived from the
C source
#include <stdio.h>
int main()
{
puts("Output.");
exit(3);
}
Within a tclsh session, notice
% catch {exec /tmp/program} result
1
% set result
Output
child process exited abnormally
% lindex $errorCode 2
3
Remember that other operations are likely to reset the value
of errorCode, so you'll generally need to preserve it in your
own named variable.
Jeffrey Hobbs contributed
this
example of a manager which schedules jobs for periodic evaluation.
Unix serial ports have names like "/dev/ttya" and "/dev/cua0".
It's easy to open one with, for example,
set sl [ open "/dev/ttya" r+ ]
Another approach, copied from David Bashaw <dbashaw@baynetworks.com>:
set port_name /dev/tty0
# This retrieves and saves current tty settings.
set tty_save [exec stty -g $port_name]
set result [exec stty -$rawmode $port_name]
open $port_name "NOCTTY" "NONBLOCK" "RDWR"
puts -nonewline $port_name "Some string\n"
...
It's easy to hang a port and process with improper EIA leads or
mis-settings in raw mode.
The latest
Tcl-DP
provides a good abstraction for serial-line programming.
D. J. Hagberg shows how to reach a pager with
DTMF-style
programming.
Loadable extension
Scott Stanton has prepared a nice
sample
dynamically loadable extension for Tcl 7.5 which works
correctly across Unix and Windowsy implementations.
Welcome screen
after 8000 { catch {destroy .welcome} }
The good folks at SCO maintain a base
example
of the
socket
command. Another appears in
Brent
Welch's book. Ray Tripamer posted a
simple
example to comp.lang.tcl. Volker Hetzer includes a socket
example on one of his many
Wiki pages,
and DKF shows much of what's involved in
telnet service
and clienthood.
Joël Saunier carefully annotates a complete, if small,
example
of a client-server pair.
Also, Mo DeJong's
EasySockets
serves not only as a alternative and easier wrapping of the base
[socket], but also as a readable example of its use.
I do plenty of networking myself. Here's a version of one of
my early client-server pairs, which I've used as the
core of several applications:
The server
set s [socket -server accept 2828]
proc accept {s a port} {
fileevent $s readable [list echo $s]
fconfigure $s -translation lf -buffering line
}
proc echo {s} {
global x
set l [gets $s]
if {[eof $s]} {
close $s
set x done
} else {
puts $s "Echoed: $l"
puts "Echoed to stdout: $l"
# gsi_return_message "Received: '$l'"
}
}
puts Ready.
vwait x; vwait x; vwait x; close $s
A client
set s [socket $HOST 2828]
fconfigure $s -buffering line
puts $s xxxxx
A UI should keep the user informed about what has happened or
is happening. I make a point of mutating the cursor to convey,
"Please wait; this operation will take several seconds more, but
it's not 'hung'." busy.tcl
is one rendering useful in that.
You can experiment with this most straightforwardly by, for example,
commanding
frame .frame1 -width 300 -height 300
pack .frame1
busy "...." [Ugh; construct a good demonstraton of this, portable to Win*OS,
in 1997.]
More on the subject appears in the Wiki
"busy".
Gerald Lester is one of many people to
answer
this FAQ.
Bill Schongar shows how to
control
Word with DDE, and specifically to
FileExit
successfully and
edit
and position.
This
is a little script which implements a
minimal text editor. It provides standard New, Open, Save, and SaveAs
functions in well under a hundred lines. It's a nice example of basic
use of the
text
and
menu
widgets, along with the
tk_get*File
and
tk_messageBox
commands.
Victor Wagner wrote a
replacement
and upgrade for Notepad in under a
day.
One very frequently-asked question is, "how can I tell when a
child process ends?" There are a numbers of ways; Alexandre
Ferrieux succinctly expresses one of the best in a
Usenet posting.
BLT has bgexec, which does this and more [document].
Along with Jeffrey Hobb's
notes
on this subject, Scott T. McColl offers
an example
of how to limit
the width of an entry widget.
Tcl doesn't have static variables of the sort on which C programmers
rely. Tcl is very adept at creating new control and data structures,
though, so it wasn't long before the community settled on a standard
idiom for this situation. At some point I'll track down proper
attribution for the fragment below, and perhaps even document it more
fully:
##
## This nice procedure allows us to use static variables. It was
## posted on the net by Karl Lehenbauer. There was another one
## which does not pollute the name space, but it fails on proc
## names or variable names with spaces in it...
##
proc static {args} {
set procName [lindex [info level [expr [info level]-1]] 0]
foreach varName $args {
uplevel 1 "upvar #0 {$procName:$varName} $varName"
}
}
What's the good of
subst?
- Tom Silva gives an
example of syntactic sugar, where it
"just makes for easier reading". Donal Fellows calls it
"invaluable" for
such cases;
- Tom Holroyd has a
related use, where subst helps Tcl
do macro processing of a tiny language for end users;
- Andreas Kupries and
Steve Ball remark on subst-ing in
entity and cross-reference resolution; and
- Steve Ball illustrates a use
in microscripting.
Mark Harrison mentions that Chapter 7 of his
Effective
Tcl ... illustrates a "'command template' [approach]
such as used by the bind command" that he finds more powerful
than subst use. The bind-like style is generally the one I've
favored.
What's a quick way to implement a "tail -f ..."? I'll give
two examples:
- An old-style, fileevent-less
one I wrote in a few minutes
requires only stock Tcl (7.3 certainly is enough), apart from
the "sleep" procedure.
- A second
example updates a wish4.2
text widget.
[A LOT of "tail -f ..." examples have been posted to c.l.t;
organizing them would be an engaging project ... The
Wiki page makes
a good start on this.]
It's fun using the text widget to build text editors, help systems,
gussied-up list boxes, or
process monitors. [Explain examples]
I argue that
traces
are underappreciated.
The Wiki has
hundreds of pages of valuable examples. That's where
I've put most of my own examples since 2000.
This small proc is a
handy way to invoke other
languages. It also illustrates use of uplevel and subst.
Want to be able to "source <URL:...>"?
This
is a simple-minded way.
WebTk is
a simple browser written in Tk.
For more extensive repositories of examples, see
the Official
Tcl/Tk Contributed Sources Archive,
the appropriate
FAQ,
and Larry Virden's
comp.lang.tcl
FAQ launcher.
[Explain all the great repositories of examples associated
with each book.]
Sunscript points to quite a
collection.
Along with the
code samples
he's long maintained, Jeffrey Hobbs has recently released a list of
pure
Tcl implementations of widgets missing from the standard
distribution.
Ken Corey has collected
several
examples.
Smiljan Gmrek points out that
vtcl, a GUI builder and
more, produces readable source. This can be a good way to generate
examples.
Jay Sekora's
jstools is a rich
deposit of nicely coded examples.
I'm a fan of Nat Pryce's great
Tcl
idioms project.
Cameron
Laird's examples of Tcl source/claird@phaseit.net