if 0 {[Richard Suchenwirth] 2004-01-25 - Languages like [Lisp] and [Python] have the ''docstring'' feature, where a string in the beginning of a function can be retrieved for on-line (or printed) documentation. Tcl doesn't have this mechanism built-in (and it would be hard to do it exactly the same way, because [everything is a string]), but a similar mechanism can easily be adopted, and it doesn't look bad in comparison: * Common Lisp: (documentation 'foo 'function) * Python: foo.__doc__ * Tcl: docstring foo If the docstring is written in comments at the top of a proc body, it is easy to parse it out. In addition, for all procs, even without docstring, you get the "signature" (proc name and arguments with defaults). The code below also serves as usage example: } proc docstring procname { # reports a proc's args and leading comments. # Multiple documentation lines are allowed. set res "{usage: $procname [uplevel 1 [list args $procname]]}" # This comment should not appear in the docstring foreach line [split [uplevel 1 [list info body $procname]]] { if {[string trim $line] eq ""} continue if ![regexp {\s*#(.+)} $line -> line] break lappend res [string trim $line] } join $res } proc args procname { # Signature of a proc: arguments with defaults set res "" foreach a [info args $procname] { if [info default $procname $a default] { lappend a $default } lappend res $a } set res } if 0 {Testing: % docstring docstring usage: docstring procname reports a proc's args and leading comments. Multiple documentation lines are allowed. % docstring args usage: args procname Signature of a proc: arguments with defaults } ---- [NEM] (23Feb2005) offers the following simple proc: # describe.tcl -- # # Simple documentation comments. # # Copyright (c) 2005 Neil Madden. # License: Tcl/BSD-style package provide describe 1.0 namespace eval describe { variable desc array set desc {} } proc describe {cmd args} { if {[llength $args] > 1} { return -code error "wrong # args: should be "describe cmd ?description?" } set name [uplevel 1 [list namespace which -command $cmd]] if {[llength $args] == 1} { set ::describe::desc($name) [lindex $args 0] } else { if {[info exists ::describe::desc($name)]} { return $::describe::desc($name) } else { return "no description available" } } } describe describe "usage: describe cmd ?description? Gets or sets a textual description associated with a command." It works like so: % describe describe usage: describe cmd ?description? Gets or sets a textual description associated with a command. % describe set no description available % describe set "usage: set var ?value? Gets or sets the current value of a variable" usage: set var ?value? Gets or sets the current value of a variable % describe set usage: set var ?value? Gets or sets the current value of a variable Advantages are that it separates the documentation from the implementation of a command, so you can add descriptions for C-coded commands (including built-ins), and you could localise the descriptions by having separate description files loaded for different languages (useful if you were using the descriptions for [tooltip]s in a GUI, say). It also works for objects, widgets, etc - anything which has a command interface. Disadvantages are that it separates the documentation from the implementation of a command ;) i.e. the descriptions may not be next to the implementations, so people may forget to keep them up-to-date. ---- [Arts and crafts of Tcl-Tk programming]