views:

1271

answers:

11

I've been working with TCL/TK ,recently started to use TCL/TK with my automation applications and I'm hungry for knowledge.

To continue with the long line of Hidden Feature questions, I would like to know any hidden or handy features of TCL/TK or any easy method to achieve some big operations

+14  A: 

When a marketing guy at Sun declared that Tcl was "Enterprise Ready", the developers added the following feature:

$ tclsh
% clock format [clock seconds] -format %Q
Stardate 63473.2
Colin Macleod
Great feature, although they seem to be ashamed of it: http://www.tcl.tk/man/tcl8.5/TclCmd/clock.htm#M58 "%Q This format group is reserved for internal use within the Tcl library."
phihag
The Stardate time format had nothing to do with Sun. I added it to Tcl while working at Scriptics, as an easter egg for the then-upcoming Tcl2K Conference. One of the conference events was a competition to implement a standard-to-stardate conversion utility, using an arcane formula. Only one guy entered the event. He spent a couple hours agonizing over the implementation (as he was looking for a job at Scriptics, he was eager to impress) only to have the easter egg revealed afterwards. Of course he won the competition anyway. And he got the job, too.
Eric Melski
Here's the CVS log for the addition: http://tcl.cvs.sourceforge.net/viewvc/tcl/tcl/unix/tclUnixTime.c?view=log#rev1.7 The "Enterprise" bit was a play on the theme of Tcl2K, which was that Tcl was the only enterprise-friendly scripting language. The manpage is deliberately vague because, of course, it is an easter egg.
Eric Melski
+3  A: 

A handy feature which is not hidden but tends not to be obvious to people coming from other languages is that you can define your own control structures (or even redefine the existing ones if you want to live dangerously). There are examples on the Tcl Wiki

Colin Macleod
+9  A: 

My favorite "hidden or handy feature" is how quoting works in Tcl. I like to use the phrase "quoting is a tool, not a rule". I also like to say "you only need curly braces when you need curly braces"

While most languages have rules for which block delimiters must be used for certain things (for example, in C you must use {} to designate a block), Tcl is not so stringent.

With Tcl, you can choose whatever quoting characters give you the effect you need. There are certainly best practices, but in the end you get to pick the quoting character that best lets you get the job done.

That means, for example, you can define a procedure in many ways, including:

proc foo {args} {
    .... body here ....
}

proc foo "args" "
    .... body here ....
"

proc foo args [some code that returns the body]

... and so on. Same goes for conditional statements, loops and everything else. (for the uninitiated, curly braces are roughly equivalent to the shell single quote, double quotes are like the shell double quote, and square brackets are like the shell backtick. ).

Now, many people look at that and say WTF? but it really gives a lot of power to the programmer. We often get questions in comp.lang.tcl along the lines of "if I do 'this {and $that}', how do I get $that to be expanded?". The answer follows the old joke "patient: doctor, it hurts when I do this doctor: don't do that". That is, if you don't like the behavior you get with one set of delimiters, choose some other delimiter. Just because an if statement is normally constructed with curly braces doesn't mean it must be constructed with curly braces.

That's my favorite "hidden" feature of Tcl. It's not hidden -- it's right on the wonderfully complete yet concise Tcl(n) man page, but the ramifications aren't clear until you fully grok how Tcl works.

Bryan Oakley
+5  A: 

Another non-obvious feature is that unrecognised commands fall through to a handler called "unknown" which you can redefine. Eg. to have unknown commands treated as expressions to evaluate:

$ tclsh
% 2+2
invalid command name "2+2"
% proc unknown args {uplevel 1 [linsert $args 0 expr]} 
% 2+2
4

More examples can be found at the wiki page on Radical Language Modification

Colin Macleod
+3  A: 

IMHO the greatest hidden feature of Tcl is its C API. Using this, it's really easy to wrap a core C program or subsystem and write a GUI or other functionality in Tcl. While this feature is not unique to Tcl, Tcl was designed to do this from the ground up and the C API is particularly easy to work with.

The second greatest hidden feature is the packer, the grand-daddy of all geometry managers. With this, a GUI can have sizeable windows with a surprisingly small amount of code. It's important to note that Tcl/Tk had geometry management at least 10 years before .net came out.

The third greatest feature of Tcl is the ability to exend the language, either through the C API or with commands defined in Tcl. Not quite LISP macros, but quite flexible nonetheless. Expect is a very good example of an application built around extending the basse Tcl language to make a domain-specific scripting language.

EDIT: well, bugger me, Xt really did have a geometry manager, although I agree with Nat in that it's somewhat more painful than pack ;-}

ConcernedOfTunbridgeWells
It's amazing that between the pack and grid geometry managers, better than 99% of all layout issues can be solved, and with very few lines of code. Contrast this to a toolkit like wxWidgets which requires at least four geometry managers to do the same job: GridSizer, FlexGridSizer, BoxSizer and StaticBoxSizer. Plus, the box sizers aren't quite as powerful as the packer, so you typically need to use one for horizontal layout and one for vertical, something the packer handles with aplomb.
Bryan Oakley
@Bryan Oakley - abso-f-ing-lutely. Hear Hear. Couldn't have put it better myself.
ConcernedOfTunbridgeWells
Xt had geometry managers before Tk, but Xt was a horrible API to work with. Tk was a breath of fresh air after having experienced the Athena and Motif widget sets.
Nat
I agree about the C API. That API and its implementation taught me a huge amount about how to write good C code. For that reason I still hold a soft spot for Tcl, despite its flaws as a language.
Nat
+4  A: 

Tcl is such a simple, open language there are very few hidden features. It's all exposed for the programmer to extend and adapt.

Nat
You make a very good point.
Bryan Oakley
TCL might be a simple language without too many commands, but they can be combined in interesting ways.
Cristian Ciupitu
+4  A: 

All of Tcl's "keywords" are regular Tcl commands, including control structures like [for], [foreach], [while], etc. This means that you can extend the language by writing new control structures in pure Tcl code.

For example, the try/on/trap structure has been implemented in Tcl 8.6a using only Tcl code. Similarly tcllib contains control::do, a do/while control structure.

A lot of this is made possible through the [upvar] and [uplevel] commands, which allow you to access variables or execute code in a different stack frame.

+6  A: 

Tcl's [trace] command allows you to intercept reads and writes to any variable. This allows you to implement an observer on any variable, and to add automatic range checking of arbitrary complexity to any variable (as if you were accessing the variable via a setter/getter). You could also create auto-incrementing variables using this technique.

proc varlimit_re {re var key op} {
  upvar $var v`
  if { [regexp -- $re $v] <= 0 } {
    error "$var out of range"
  }
}

trace add variable ::myvar {write} [list varlimit_re {^[A-H]\d{3}-[0-9a-f]+$}]`

If you try to set 'myvar' to anything that doesn't match the regular expression, you will get a runtime error.

+1  A: 

The well documented C API also allowed easy integration in Perl. My experience with Tcl/Tk goes back to 1995, but in 2000 or so, I discovered Perl/Tk and never looked back.

And lately, the Tcl and Tkx Perl packages give us modern-looking GUI's. And the two aforementioned modules, while not trivial, involve relatively little code, considering what they allow one to do across language boundaries. And that can be directly attributable to the excellent API (and the power of Perl, obviously).

xcramps
+2  A: 
  1. [array names] is one of the first questions newbies ask about how to iterate over an array
  2. also, the fact that you can foreach {key1 key2} {$list1 $list2} {...} - even if the lists are of different size
  3. you should not use comments between switch cases (this is not a cool feature but a problem most developers do not understand
  4. the rename command can rename any function/proc
Nir Levy
That last one is part of what gives the Tcl programmer so much flexibility. How many other languages let you redefine "if" or "return"? And while there is very, very rarely ever a time when you need to rename core commands, the one time you do you'll be very happy you can.
Bryan Oakley
+1  A: 

I think the time command is wonderful. It's not exactly hidden but that doesn't stop people from asking "which function is faster" once in a while in comp.lang.tcl.

Anytime you want to know "how long does this take?" or "which method is faster?" you just call it via the "time" command. No creating of objects, no math, no overhead, exceptionally simple. Other languages have a similar feature, though some are a bit less elegant.

Bryan Oakley