Previous section   Next section

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 14.  Namespaces

Using Namespaces

Namespaces add new syntax to procedure and variable names. A double colon, ::, separates the namespace name from the variable or procedure name. You use this syntax to reference procedures and variables in a different namespace. The namespace import command lets you name things in other namespaces without the extra syntax. Namespaces can be nested, so you can create a hierarchy of scopes. These concepts are explained in more detail in the rest of this chapter.

One feature not provided by namespaces is any sort of protection, or a way to enforce access controls between different namespaces. This sort of thing is awkward, if not impossible, to provide in a dynamic language like Tcl. For example, you are always free to use namespace eval to reach into any other namespace. Instead of providing strict controls, namespaces are meant to provide structure that enables large scale programming.

The package facility described in Chapter 12 was designed before namespaces. This chapter illustrates a style that ties the two facilities together, but they are not strictly related. It is possible to create a package named A that implements a namespace B, or to use a package without namespaces, or a namespace without a package. However, it makes sense to use the facilities together.

Example 14-1 repeats the random number generator from Example 7-4 on page 85 using namespaces. The standard naming style conventions for namespaces use lowercase:

Example 14-1 Random number generator using namespaces.
package provide random 1.0

namespace eval random {
   # Create a variable inside the namespace
   variable seed [clock seconds]

   # Make the procedures visible to namespace import
   namespace export init random range

   # Create procedures inside the namespace
   proc init { value } {
      variable seed
      set seed $value
   proc random {} {
      variable seed
      set seed [expr ($seed*9301 + 49297) % 233280]
      return [expr $seed/double(233280)]
   proc range { range } {
      expr int([random]*$range)

Example 14-1 defines three procedures and a variable inside the namespace random. From inside the namespace, you can use these procedures and variables directly. From outside the namespace, you use the :: syntax for namespace qualifiers. For example, the state variable is just seed within the namespace, but you use random::seed to refer to the variable from outside the namespace. Using the procedures looks like this:

=> 0.3993355624142661
random::range 10
=> 4

If you use a package a lot you can import its procedures. A namespace declares what procedures can be imported with the namespace export command. Once you import a procedure, you can use it without a qualified name:

namespace import random::random
=> 0.54342849794238679

Importing and exporting are described in more detail later.

      Previous section   Next section