Previous section   Next section

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

Table of Contents
Chapter 12.  Script Libraries and Packages

Using Packages

Each script file in a library declares what package it implements with the package provide command:

package provide name version

The name identifies the package, and the version has a major.minor format. The convention is that the minor version number can change and the package implementation will still be compatible. If the package changes in an incompatible way, then the major version number should change. For example, Chapter 17 defines several procedures that use the HTTP network protocol. These include Http_Open, Http_Get, and Http_Validate. The file that contains the procedures starts with this command:

package provide Http 1.0

Case is significant in package names. In particular, the package that comes with Tcl is named http ?all lowercase.

More than one file can contribute to the same package simply by specifying the same name and version. In addition, different versions of the same package can be kept in the same directory but in different files.

An application specifies the packages it needs with the package require command:

package require name ?version? ?-exact?

If the version is left off, then the highest available version is loaded. Otherwise the highest version with the same major number is loaded. For example, if the client requires version 1.1, version 1.2 could be loaded if it exists, but versions 1.0 and 2.0 would not be loaded. You can restrict the package to a specific version with the -exact flag. If no matching version can be found, then the package require command raises an error.

Loading Packages Automatically

The package require command depends on an index to record which files implement which packages. The index must be maintained by you, your project librarian, or your system administrator when packages change. The index is computed by the pkg_mkIndex command that puts the results into the pkgIndex.tcl file in each library directory. The pkg_mkIndex command takes the name of a directory and one or more glob patterns that specify files within that directory. File name patterns are described on page 115. The syntax is:

pkg_mkIndex ?options? directory pattern ?pattern ...?

For example:

pkg_mkIndex /usr/local/lib/welchbook *.tcl
pkg_mkIndex -direct /usr/local/lib/Sybtcl *.so

The pkg_mkIndex command sources or loads all the files matched by the pattern, detects what packages they provide, and computes the index. You should be aware of this behavior because it works well only for libraries. If the pkg_mkIndex command hangs or starts random applications, it is because it sourced an application file instead of a library file.

By default, the index created by pkg_mkIndex contains commands that set up the auto_index array used to automatically load commands when they are first used. This means that code does not get loaded when your script does a package require. If you want the package to be loaded right away, specify the -direct flag to pkg_mkIndex so that it creates an index file with source and load commands. The pkg_mkIndex options are summarized in Table 12-1.

Table 12-1. Options to the pkg_mkIndex command.
-directGenerates an index with source and load commands in it. This results in packages being loaded directly as a result of package require.
-load patternDynamically loads packages that match pattern into the slave interpreter used to compute the index. A common reason to need this is with the tcbload package needed to load .tbc files compiled with TclPro Compiler.
-verboseDisplays the name of each file processed and any errors that occur.

Packages Implemented in C Code

The files in a library can be either script files that define Tcl procedures or binary files in shared library format that define Tcl commands in compiled code (i.e., a Dynamic Link Library (DLL)). Chapter 44 describes how to implement Tcl commands in C. There is a C API to the package facility that you use to declare the package name for your commands. This is shown in Example 44-1 on page 610. Chapter 37 also describes the Tcl load command that is used instead of source to link in shared libraries. The pkg_mkIndex command also handles shared libraries:

pkg_mkIndex directory *.tcl *.so *.shlib *.dll

In this example, .so, .shlib, and .dll are file suffixes for shared libraries on UNIX, Macintosh, and Windows systems, respectively. You can have packages that have some of their commands implemented in C, and some implemented as Tcl procedures. The script files and the shared library must simply declare that they implement the same package. The pkg_mkIndex procedure will detect this and set up the auto_index, so some commands are defined by sourcing scripts, and some are defined by loading shared libraries.

If your file servers support more than one machine architecture, such as Solaris and Linux systems, you probably keep the shared library files in machine-specific directories. In this case the auto_path should also list the machine-specific directory so that the shared libraries there can be loaded automatically. If your system administrator configured the Tcl installation properly, this should already be set up. If not, or you have your shared libraries in a nonstandard place, you must append the location to the auto_path variable.

      Previous section   Next section