TIP 44: Move Tk's Private Commands and Variables into ::tk Namespace

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2017 Conference, Houston/TX, US, Oct 16-20
Send your abstracts to tclconference@googlegroups.com
by Aug 21.
Author:         Don Porter <dgp@users.sourceforge.net>
State:          Final
Type:           Project
Vote:           Done
Created:        16-Jul-2001
Post-History:   
Tcl-Version:    8.4

Abstract

This TIP proposes that Tk's private commands and variables be moved into the namespace ::tk or its descendent namespace(s).

Background

Tk defines several commands and variables in the global namespace that are not intended for public use. Some of the commands are used for widget bindings. Some of the variables are used to maintain widget state information. The definition of these "private" commands and variables in the global namespace is a legacy held over from Tk 4 and the pre-8 versions of Tcl in which there was only one namespace.

Fortunately, the coders of Tk have maintained good discipline in naming these commands and variables intended for Tk's internal use only. The commands and variables matching the glob pattern ::tk[A-Z]* are private. Consider this interactive tktest session with Tk 8.3.3:

 $ cd tk/unix
 $ make runtest
 ...
 % # Put Tk through its paces to define all commands and variables
 % source ./../tests/all.tcl
 ...
 % llength [info commands {tk[A-Z]*}]
 183
 % llength [info vars {tk[A-Z]*}]
 5

So, on Unix, there are 183 private commands and 5 private variables polluting the global namespace. The number and list of commands and variables varies a bit from platform to platform due to differences in widget bindings.

More recently, private commands in Tk have been added in the ::tk namespace; two examples are tk::PlaceWindow and tk::SetFocusGrab. Likewise the private variable tk::FocusGrab has also been added in the ::tk namespace.

There are three reasons why it is better for Tk's private commands and variables to be moved out of the global namespace and into the ::tk namespace.

  1. The large number of commands and variable makes it more difficult to use interactive [info commands] and [info vars] or [info globals] introspection to learn about what application specific commands and variables are defined.

  2. Placing private commands and variables in the global namespace gives them a higher profile, and increases the likelihood that they will be used publicly, against the intent of Tk's interface.

  3. By making more use of its own namespace for keeping track of its own internals, Tk becomes a better example for authors of other packages to copy.

Proposal

All commands and variables created by Tk and matching the glob pattern ::tk[A-Z]* shall be renamed to a name contained within the ::tk namespace or one of the descendent namespaces of ::tk.

The global variable ::histNum created by tk/library/console.tcl shall also be renamed to ::tk::HistNum.

All commands and variables created by the proposal will be given names that begin with an uppercase character ([A-Z]) to indicate their internal status according to the conventions of the Tcl Style Guide http://purl.org/tcl/home/doc/styleGuide.pdf .

Compatibility and Migration

This proposal only deals with the internals of Tk, so technically there are no compatibility issues, because Tk users should not be depending on these private commands and variables.

That said, because these commands and variables have had a high profile in the global namespace, it seems likely that some users have written code that depends on them. To aid such users in a migration away from that dependence, it is also proposed that Tk provide two additional unsupported commands:

 ::tk::unsupported::ExposePrivateCommand commandName

and

 ::tk::unsupported::ExposePrivateVariable variableName

The command [::tk::unsupported::ExposePrivateCommand commandName] restores the existence of the Tk private command commandName in the global namespace as it was before adoption of this proposal. The command [::tk::unsupported::ExposePrivateVariable variableName] restores the existence of the Tk private variable variableName in the global namespace as it was before adoption of this proposal. For example, a Tk user who had written code that made use of the Tk private command tkCancelRepeat can add the following code to continue working with Tk after acceptance of this proposal:

 if {![llength [info commands tkCancelRepeat]]} {
     tk::unsupported::ExposePrivateCommand tkCancelRepeat
 }

These migration commands are in the namespace tk::unsupported, a new namespace to be used for unsupported commands in Tk. This namespace may and should be used for any other unsupported commands to be created in Tk. Their implementation is in the new file tk/library/unsupported.tcl.

Reference Implementation

This proposal has already been implemented and committed to Tk's CVS repository on the branch tagged dgp-privates-into-namespace. That branch is up to date with Tk's HEAD branch as of July 16, 2001.

To make an anonymous checkout of the reference implementation into a directory named tkprivate, run the following CVS commands:

 $ cvs -d :pserver:anonymous@cvs.tktoolkit.sf.net:/cvsroot/tktoolkit \
   login
 (Logging in to anonymous@cvs.tktoolkit.sf.net)
 CVS password: <Enter>
 $ cvs -z3 -d :pserver:anonymous@cvs.tktoolkit.sf.net:/cvsroot/tktoolkit \
   co -r dgp-privates-into-namespace -d tkprivate tk

The reference implementation has the same results on the Tk test suite as the HEAD revision.

In the tktest of the reference implementation:

 $ make runtest
 ...
 % source ./../tests/all.tcl
 ...
 % llength [info commands {tk[A-Z]*}]
 0
 % llength [info vars {tk[A-Z]*}]
 0

See Also

Feature Request 220936 http://sf.net/tracker/?func=detail&aid=220936&group_id=12997&atid=362997

Related Ideas / Future Work

The ideas in this section are not part of this proposal. They are related ideas mentioned here as explicitly outside the scope of this proposal so they will not be counter-proposed.

Copyright

This document has been placed in the public domain.

History