Minh Le
Minh Le

Reputation: 23

How should I manage too many TCL procedures?

Me and my team have been working on multiple tools flow for awhile now.

We keep adding new procedure in either a same file or creating new file in the same directory. There are also a lot of nested procedures; one calls others.

The number of procedures will only keep growing, and the flow involves at least 10 people who love to do their own things.

My question is, how would we go about managing all these procedures in a tidy manner?

Upvotes: 1

Views: 126

Answers (2)

Donal Fellows
Donal Fellows

Reputation: 137797

We assume you follow good practices with general software engineering (keeping files in source control, etc.) as without those you're stuck anyway.

Tcl doesn't really support nested procs; you can call proc from inside another procedure, but it doesn't do any kind of scoping.


You should be thinking in terms of dividing up your code into pieces of “coherent API”. What exactly that is depends on your application, but it is only rarely a single procedure; a particular dialog box or screen is a much more useful unit. That might end up as one procedure, but it's often several related ones.

Once you've identified these coherent pieces, they form the contents of what you put in a file, typically one coherent piece per file, though if the file is rather long when you do that, using a group of files instead (probably in their own directory) makes a lot of sense. At the same time, you probably should make the variables and commands defined by each coherent piece be all in a Tcl namespace, which isolates the piece a little bit from the rest of the world, mostly to stop code from treading on the toes of other code.

Now that you've done that, and if you've got what you think is a stable API to your coherent piece, you can make that piece into a Tcl package. That's just done by giving it a higher-level name and version number; you put this in one of your files in the coherent piece:

package provide YourPackageName 1.0

and then (usually in the same directory) you make a pkgIndex.tcl file with contents like this:

package ifneeded YourPackageName 1.0 [list source [file join $dir yourFilename.tcl]]

That is, it says that to get YourPackageName version 1.0 in a Tcl interpreter, you source the file $dir/yourFilename.tcl; the $dir is a convenience in package index files that refers to the directory containing the current package index file. Then the rest of your code can stop thinking about “reading the right files”, and start thinking in terms of “use this defined API”. (This is great if you then choose to start implementing the package using a mixture of Tcl and C or even pure C code; a change to the index file to use load of the right thing and everything else can be oblivious.) It does that by doing:

package require YourPackageName
# Give the version if necessary, of course

Then write yourself some documentation (even if it is just listing the entry point commands into the package) and tests, and you've migrated to being a very well behaved piece of code indeed.


There are some additional techniques that can help you in some cases with making coherent pieces. In particular, if you're using an OO system like TclOO, iTcl, or XOTcl, each class is almost certainly a candidate coherent piece. Also, it's sometimes better to put several related coherent pieces together in a package. However, there's absolutely no hard and fast rule on that.

Finally, Tcl uses a bunch of techniques to find packages, but they mostly come down to looking using the auto_path global variable. In your application main script, it's best (if the rest of your code is mostly in the library directory) to use something like this as one of the first steps:

lappend auto_path [file join [file dirname [info script]] library]

You can also gather the contents of many pkgIndex.tcl files in one place, provided you take into account any pathname changes needed from moving things around.

Upvotes: 6

Anuj Gupta
Anuj Gupta

Reputation: 135

So regarding the TCL, You can look for creating the packages and namespaces. Let me know if that can help. So more details can be provided

Upvotes: 1

Related Questions