This is not necessarily the current version of this TIP.
| TIP: | 229 |
| Title: | Scripted Control of Name Resolution in Namespaces |
| Version: | $Revision: 1.6 $ |
| Author: | Donal K. Fellows <donal dot k dot fellows at man dot ac dot uk> |
| State: | Draft |
| Type: | Project |
| Tcl-Version: | 8.5 |
| Vote: | Pending |
| Created: | Wednesday, 03 November 2004 |
This TIP proposes extensions to the namespace command to allow scripts to control how individual namespaces map names to commands.
Tcl has, for historic reasons, attracted many different styles of object system, and a favoured mechanism for implementing objects is on top of namespaces (which were introduced in Tcl 8.0 based on work done previously in [incr Tcl]). However, a common problem that these OO systems face is the inability to make namespaces efficiently map names of entities within classes etc. into the object instances. This TIP provides a simple mechanism for doing this.
No mechanism is provided for affecting the resolving of variable names. Best practice is to ensure that variables not present in the current namespace are imported explicitly through the upvar or variable commands (depending on context) and the fact that there is any possibility of non-local variable name resolution has been behind a number of bugs in the core (e.g. Bug #981733).
The namespace command will gain a new subcommand, path, with the following syntax:
namespace path ?list?
This command sets and queries the current namespace's command name resolution path. If list is present, namespace path sets the path to the list of namespaces named in the list and returns the empty string; all the namespaces must exist or an error is thrown. If no list argument is provided, namespace path doesn't change anything and returns the current path.
The info commands command shall be updated so that, when no namespace is present in its pattern part, it shall return all (matching) commands that are visible without namespace qualifiers at this point. The info procs command will not be so modified.
Only names without a namespace separator in them are resolved using the namespace's path (names starting with a namespace separator are always resolved with respect to the root of the namespace hierarchy, and it is massively easier to only resolve local names instead of names with a namespace component as well). When resolving command names, the current namespace is always (unless a resolver is installed, of course) preferred, and the global namespace is always checked after everything in the path. This means that the old behaviour is exactly what you get when the path is empty, and also ensures that virtually all scripts continue to work when a path is set; if it was possible to remove the global namespace from the actual path (as opposed to the settable part), virtually all scripts would break. If an extension installs a custom name resolver, that completely overrides the command name resolution path mechanism (to maximize backward-compatability; it is not anticipated that much code will try to mix the two mechanisms in a namespace).
Note that each namespace's path is isolated from the path of every other namespace, including the parent namespace. Systems using the namespace path mechanism as part of an implementation of inheritance will want to set up the path for each object namespace explicitly (this value can be statically precomputed on a per-class basis); indeed, where multiple inheritance is involved it will probably be more efficient to compute the path than let Tcl guess.
The path is parsed completely at the time the namespace path command is run, and the resulting list of namespaces is used directly. If a namespace on some namespaces' path is deleted, it is immediately excised from the path of every namespace that refers to it.
A patch is available[1].
This document has been placed in the public domain.
This is not necessarily the current version of this TIP.