TIP #229: Scripted Control of Name Resolution in Namespaces
_____________________________________________________________________________
TIP:	229
Title:	Scripted Control of Name Resolution in Namespaces
Version:	$Revision: 1.10 $
Authors:	Donal K. Fellows <donal.k.fellows@man.ac.uk>
State:	Final
Type:	Project
Tcl-Version:	8.5
Vote:	Done
Created:	Wed Nov 03 00:00:00 UTC 2004
Abstract
This TIP proposes extensions to the namespace command to allow scripts to control how individual namespaces map names to commands.
Rationale
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).
Proposed Change
Namespace Path Subcommand
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.
Updates to Other Commands
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.
Name Path Behaviour
Only names without a leading namespace separator in them are resolved using the namespace's path. When resolving command names, resolving relative to the current namespace is always preferred (unless a resolver is installed, of course), and resolution relative to the global namespace is always done after resolving relative to everything in the path (unless the global namespace is explicitly in the path, when it happens earlier). 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.
Examples
The following script returns "::foo":
namespace eval ::foo 
   proc boo  namespace current
   namespace eval bar 
      namespace path ::foo
      boo

The following script return "::foo::bar":
namespace eval ::foo 
   proc boo  namespace current
   namespace eval bar 
      proc boo  namespace current
   
   namesspace eval spong 
      namespace path ::foo
      bar::boo

Implementation
A patch is available[http://sf.net/tracker/?func=detail&aid=1159942&group_id=10894&atid=310894].
Copyright
This document has been placed in the public domain.
_____________________________________________________________________________
Colophon
TIP AutoGenerator - written by Donal K. Fellows