Ziff-Davis Enterprise 
DevSource: Microsoft Developer Resource
Add OnsArchitectureLanguagesTechniquesUsing VSForums
 
Home arrow Languages arrow Page 2 - Five Surprises from Tcl
Five Surprises from Tcl
By Jeffrey Hobbs

Rate This Article:
Add This Article To:
Five Surprises from Tcl - ' Networking, RSS, '
( Page 2 of 4 )

& Unicode">

Tcl is our favorite language for achieving big results with small, understandable programs. Lots of developers, though, don't know about Tcl, or think of it only as an off-beat, old-fashioned, Unix-specific language with no definite advantages — "a fringe language only used by cults" is a description we heard just last week. People who believe that miss out on:

  • simple asynchronous event-based networking;
  • quick-and-easy Unicode-savvy GUI programming;
  • compact game authoring;
  • virtual file systems; and
  • a uniquely potent deployment technology that makes cross-platform development and installation a breeze.
Slick Networking

We expect you to understand the examples which follow deeply. They aren't just "literary exercises" for abstract study, but real, useful, working programs. Even on a computer completely barren of Tcl facilities, you can download in ten minutes enough of a Tcl development or runtime environment to run these examples and start modifying them to your own ends. More than that, you should expect to understand your Tcl experiments. Tcl has only twelve syntax rules, and most programs confine themselves to fewer than the full dozen.

ADVERTISEMENT

One distinctive Tcl feature is the event loop it builds in. Event-oriented programming makes it possible to create simple services that handle multiple simultaneous connections with only a few lines of code. The example below creates a simple network server that accepts mathematical expressions and returns their results.

    # Create a safe interpreter with Tcl's
    # excellent sandbox facilities.  Each
    # client receives his own interpreter,
    # so the actions of one client can't
    # harm any other client, or the server
    # itself.
    interp create -safe calc

    proc accept {sock ip port} {
        # Configure the socket to be non-blocking.
        fconfigure $sock -blocking 0 -buffering line
        # Call the 'respond' proc whenever
	# the socket has data for us.
        fileevent $sock readable [list respond $sock]
    }

    proc respond {sock} {
        # If we can no longer read from sock, close it.
        if {[catch {read -nonewline $sock} data] || [eof $sock]} {
           catch {close $sock}
           return
        }
        # safe calculator style evaluator
        catch {interp eval calc [list expr $data]} result
        # push result back down the socket
        puts $sock $result
    }

    # Create our server on port 7272
    socket -server accept 7272

    # Drop Tcl into the event loop
    vwait forever

That's all. At this point, you have a secure, multi-tasking network server that properly handles multiple clients, connecting and disconnecting arbitrarily. To exercise the server, you need only "telnet SERVER 7272", and submit lines such as "3 + 4" or "0.75 * sin(3.14 / 12)".

You don't have to use telnet, of course. A Tcl-coded client can be even briefer than the server! Try this:

       set s [socket localhost 7272] ; # open port to server
       fconfigure $s -buffering line ; # flush on newlines
       puts $s "5+5"                 ; # send an expression
       gets $s                       ; # get the result
    =>  10

Don't let these brief examples persuade you that Tcl is only good for tiny programs. Our commercial deliveries include as many as a quarter-million lines of Tcl code. Somewhere between the few-line scripts and enterprise-class megaprograms is the "RSS reaper."

An RSS Reader

Richard Suchenwirth, a development engineer for a Siemens division in Konstanz, wanted a quick, compact application that would "reap" fresh RSS news to his iPaq for offline reading. Advertisements, elaborate frames, hyperlinks, and so on are just overhead that he avoids for this use.

His solution is a small Tcl script of under a hundred lines. If you invoke it under any operating system with, for example,

tclsh rss2html.tcl
http://news.bbc.co.uk/rss/newsonline_world_edition/front_page/rss091.xml
BBC.html

The program collects the latest headlines from the BBC RSS source. Last weekend, for example, it produced a file which Internet Explorer rendered like this:

Suchenwirth has contributed hundreds of little utilities and entertainments like the RSS Reaper to the Tcl community. His style typically is easy to read, even for those new to the language. In this particular implementation, perhaps the most challenging fragment is geturl_followRedirects. Tcl builds in a delightfully elegant networking programming interface which, for example, makes creation of a multitasking server a two-line affair. "Out of the box", though, Tcl leaves HTTP redirects to the programmer. To handle these properly, Suchenwirth defines a procedure geturl_followRedirects:

1     proc geturl_followRedirects {url} {
2        array set URI [::uri::split $url] ;# Need host info from here
3        while {1} {
4            set token [http::geturl $url]
5            if {![string match {30[1237]} [::http::ncode $token]]} {
6  	         return $token
7  	     }
8            array set meta [set ${token}(meta)]
9            if {![info exist meta(Location)]} {
10               return $token
11           }
12           array set uri [::uri::split $meta(Location)]
13           unset meta
14           if {$uri(host) == "} { set uri(host) $URI(host) }
15           set url [eval ::uri::join [array get uri]]
16       }
17    }

For Tcl, procedures serve roughly as functions do in C, or subroutines in Basic. In this particular procedure, line 2 takes apart a URL, like http://devsource.com/index.html, into constituent elements, including "http", "devsource.com", and "index.html". The results are assigned to an "associative array" called URI. Tcl's arrays are what other languages sometimes call "hashes" or "dictionaries." Tcl also has C- or Fortran-like arrays, but calls them "lists."

Code Commentary

Line 3 starts a "forever loop", one that redirects through HTTP references until termination.

Line 4 makes an HTTP request, and stores a handle, or "token", to the result, in the variable called token.

Lines 5-7 detect basic HTTP status codes, and return the handle unless the code specifies redirection, that is unless the status is one of 301, 302, 303, or 307. If there is redirection, but without a Location, then it's best to return the handle immediately, as lines 8-11 do.

Otherwise, the procedure constructs a new HTTP request, and loops. As HTTP responses can have not just different meta-values, but even different keys or attributes, line 13 clears out the entire meta array. This prevents an attribute from one request still being present for a subsequent redirection.

Line 14 accomodates those pages redirects which default the hostname. If a hostname isn't specified, then the redirect is assumed to appear on the host of the redirection.

Line 15 builds a URL string from its constituents — "http://devsource.com", for example, from a "scheme" of "http" and hostname of "devsource.com". The eval is part of a Tcl idiom for grouping, to translate between a single item which is a list and the list of single items that ::uri::join expects. An example of this difference is:

::uri::join "scheme http host devsource.com"

and

::uri::join scheme http host devsource.com

In the first, ::uri::join is passed a single argument, while it receives four in the second.

Unicode Potency

As a polyglot whose customers are often overseas, Suchenwirth has made particularly profound use of Tcl's Unicode abilities. His i18n tester shows on any host how different installed fonts look.

Here's its complete source:

package require Tk
pack [text .t -font {Helvetica 16}]
.t insert end "
Arabic \uFE94\uFEF4\uFE91\uFEAE\uFECC\uFEDF\uFE8D\uFE94\uFEE4\uFEE0\uFEDC\uFEDF\uFE8D
Trad. Chinese \u4E2D\u570B\u7684\u6F22\u5B57
Simplified Chinese \u6C49\u8BED
Greek \u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC\u03B3\u03BB\u03CE\u03C3\u03C3\u03B1
Hebrew \u05DD\u05D9\u05DC\u05E9\u05D5\u05E8\u05D9\u05DC\u05D9\u05D0\u05E8\u05E9\u05D9
Japanese \u65E5\u672C\u8A9E\u306E\u3072\u3089\u304C\u306A,\u6F22\u5B57\u3068\u30AB\u30BF\u30AB\u30CA
Korean \uB300\uD55C\uBBFC\uAD6D\uC758 \uD55C\uAE00 (\u3CA2\u3498)
Russian \u0420\u0443\u0441\u0441\u043A\u0438\u0439\u044F\u0437\u044B\u043A
"

package require Tk declares this as a graphical user interface (GUI) application.

The pack creates a text area with a default font, and renders on the display. The .t insert ... line inserts the texts seen in the figure.

Tcl was one of the first dynamic languages to manage full Unicode conveniently; it's still one of Tcl's strengths. From a programmer's standpoint, Tcl characters are just characters; if they happen to be from an extended Unicode page, the language simply does the right thing with them. They're fully accessible, at the same time, in that Tcl has facilities for translating between different encodings, and to "binary", in particular. Tcl handles translations to the system transparently, including filesystem access.



 
 
>>> More Languages Articles          >>> More By Jeffrey Hobbs
 



DevSource video
Devsource Video Series
Manipulating Society through Technology
Jeremy Bailenson, Director of the Virtual Human Interaction Lab at Stanford University, talks about virtual reality, avatars, Moore's law, how real world behaviors influence online reality, and societal manipulation through technology!
>> Play video
>> Read article
>> See all videos
DevLife Blog
Julia looks at the changes to ADO.NET!
MSDev Blog
Is the latest Delphi product, RAD Studio 2007, really necessary?
Make it Work
.NET makes runtime type checking a breeze. See what Peter has to say about it in this week's tips!
News
Microsoft Counts on App Support for Vista
Microsoft has taken pains to demonstrate that Windows Vista will have ample application support.
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.