auto_mkindex

auto_mkindex, a command in the Tcl Library, generates an index suitable for use by auto_load, writing it to a file named tclIndex.


If you want to use auto_mkindex with itcl or any other extension that declares special proc-like constructs, be certain package require the extension first. For example:

$ tclsh
% package require Itcl
3.3
% auto_mkindex . *.tcl *.itb *.ith

MSW 2003-09-03: What does auto_mkindex buy us over auto_mkindex_old (which I prefer), given that auto_mkindex_old has a clear rule how to exclude procedures from loading, and auto_mkindex doesn't ?

Imagine e.g. you have a library of Tcl stuff, with different (Gui or not) frontends all having a common init procedure which they cannot auto_load (yet) because they did not setup load paths ($auto_path). Now if you e.g. start in a non-gui case, calling an init procedure (let's call it xxx_init) which you put in an init.tcl, it's absolutely random which file ends up being loaded (or the last alphabetically sorted), which often is not the right thing - that last file could be using xxx_init to set up things, but when it's sourced could call it with some parameters which apply for the GUI case only.

Checking against the $argv0 won't help, as this same thing can also be in a subwindow or own toplevel when started from another (GUI) script in the bundle...

So if someone has some insight to share on what the new auto_mkindex really buys us, I'm curious.

DGP Well, I tend to agree that the "new" (1998?) features of auto_mkindex are more trouble than they are worth. The main new functionality is that auto_mkindex is extensible. The older auto_mkindex_old indexes procs only, recognizing them by the literal text string proc. The newer auto_mkindex can be configured to treat any command as a command-defining command, for example itcl::class, resulting in a more complete index of the commands produced by sourcing a file. If you don't make use of any packages that define new command-defining commands, and you just like the older one better, it's still there, feel free to use it.

MSW: See, that's a good answer finally. Actually I'm not that hard about it, auto_mkindex_old is there after all, and I guess it'll be some minor revisions before it goes away... I was, given I debugged that for ages after switching from 8.3.2 to 8.3.5, a bit pissed about it, too, luckily I found auto_mkindex_old before having to dive into auto.tcl... Thanks to both of you :)


RS 2003-09-03: auto_mkindex_old does not exclude procs from loading - only they are not indexed. If the file is sourced because of another proc, all the ;procs will be loaded too. But with unique names (namespaces), conflicts should not occur. Also consider the package mechanism for more modular (and versioned) code management.


MSW 2003-09-03: Uh, sorry. I meant not being indexed. Yet not being indexed means you know which file will be loaded. Of course I can add a plethora of bookhandling code, too. And until package require pkg arg doesn't accept anything as arg, it's pretty useless for variable behaviour, while you keep developing your packages. That was not the question either, I asked why abandon an easily controllable interface towards one where you either have to dig deeper, add more code or more complexity.

file init-proc.tcl:

proc xxx_init {{do_this 0} {do_that 0} {do_gui 0}} {
    # do something shared
    # do something according to params
}

file 1.tcl (executable, gui):

> ;  proc xxx_init ...
> standalone usage: 1.tcl: xxx_init 1 0 1
> loaded: we need that init stuff, too ( as of the options )

file 2.tcl (executable, gui):

> as 1.tcl

file 3.tcl (executable, !gui):

> ; proc xxx_init ...
> standalone usage: 3.tcl: xxx_init

file 4.tcl (executable, gui):

> as 1.tcl

5 (statically compiled c program with tcl interpreter)

> in Tcl_AppInit, call xxx_init. With new auto_mkindex
> ran, 4.tcl will be loaded (has gui -> Bang!)
> with old, init-proc.tcl will be loaded

alternative to get old behaviour: source full/path/init-proc.tcl.

rephrase alternative in other ways: abandon autoloading (in my case of course). uh huh. So that's what auto_mkindex(_new) buys me ?


RS: This seems more like a discipline problem to me - I've learnt (the hard way) that, when using autoloading, one should clearly divide one's files into two classes:

  • apps (which do something, but should not be in an auto-indexed directory)
  • lib files (which do nothing except define procedures, and maybe set variables), and are auto-indexed

A compromise is however possible, if you must have lib and app functionality in the same file. I often use this for demo or self-test, to have the last part of the file like this:

if {[info exists argv0] && [file tail [info script]] eq [file tail $argv0]} {
    ... ;# demo UI, or tests that report to [stdout], etc.
}

The if condition is only true for the the script that is sourced as a result of being an argument to tclsh, and allows to ship test cases in the same file with the library functions.

See main script.


MSW 2003-09-03: your idea works fine if the app script is itself called, but not when it is source via another app script, to display its gui in e.g. another toplevel or frame, while it (the second, sourced app) still needs its own initalization. $argv0 and file tail [info script] will differ. Plus discipline is not that easy if you're grooming some dozen K's LOC tcl code and features are pressing ... :)