Example fragments of Tcl source

Table of contents

Fileevent

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]

Does this string represent a number?

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.

Flashing widget

Bob Techentin offers a concise example of a flashing button. Nat Pryce explains the principle in detail.

Fonts

Donal K. Fellows' font previewer is far more than just a simple example.

FTP

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."

Glue

[Explain Sunlab's example of dynamic loading.]

HTTP

Victor Wagner nicely illustrates how easy it is to conduct HTTP business, even without the newer commands introduced with version X.X.

IP address

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 ...

Mail

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.

Progress bar

[... later ...]

Return values

"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.

Job scheduling

Jeffrey Hobbs contributed this example of a manager which schedules jobs for periodic evaluation.

Serial line programming

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} }

Simple socket communications

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

Clock face

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".

Centering a window on the screen

Gerald Lester is one of many people to answer this FAQ.

DDE

Bill Schongar shows how to control Word with DDE, and specifically to FileExit successfully and edit and position.

Editor

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.

End-of-process

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].

Entry of limited width

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.

static variables

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"
      }
  }

subst

What's the good of subst? 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.

tail -f

What's a quick way to implement a "tail -f ..."? I'll give two examples: [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.]

Text

It's fun using the text widget to build text editors, help systems, gussied-up list boxes, or process monitors. [Explain examples]

Trace

I argue that traces are underappreciated.

Coding in other languages

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.

Generalizing the file system

Want to be able to "source <URL:...>"? This is a simple-minded way.

WebTk is a simple browser written in Tk.

Other collections

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