package ifneeded

package ifneeded package version ?script?

This command typically appears only in system configuration scripts to set up the package database. It indicates that a particular version of a particular package is available if needed, and that the package can be added to the interpreter by executing script. The script is saved in a database for use by subsequent package require commands; typically, script sets up auto-loading for the commands in the package (or calls load and/or source directly), then invokes package provide to indicate that the package is present. There may be information in the database for several different versions of a single package. If the database already contains information for package and version, the new script replaces the existing one. If the script argument is omitted, the current script for version version of package package is returned, or an empty string if no package ifneeded command has been invoked for this package and version.


The package selection algorithms inside package require need to trust that the package ifneeded commands have provided accurate information. That is, in order for package version selection to work properly, it needs to be true that the command

package ifneeded $pkg $version $script

accurately and truthfully indicates that

uplevel #0 $script

will cause the command

package provide $pkg $version

to be evaluated (or equivalent Tcl_PkgProvide call), or, perhaps in some unusual circumstances for the $script evaluation to raise an error so that the inability to load and initialize version $version of package $pkg can be reported by the failing package require.

Because the package provide operation is a side effect of evaluation of $script, and because evaluation of $script is not something that package ifneeded is supposed to do, there is no way for the package ifneeded command itself to test for inaccuracies like this. Even the package require command cannot check for these inaccuracies before making a selection based on trusting the claims as accurate and attempting to evaluate $script. The best that can be done is to check after the fact whether the version $version of package $pkg that was promised was in fact delivered, and if not, to raise an error and package forget any improper version that might have been package provided instead.

Tcl 8.5 does this post-script evaluation check for incorrect package ifneeded comands. If the index script for some installed package is broken in this way, promising a version different from the version it actually delivers, Tcl 8.5 will no longer tolerate this brokenness and any package require that load the broken package will error out and no version of $pkg will be left provided in the interp.

Because Tcl used to tolerate this error, there are many broken packages out there that need correcting in order to operate successfully with Tcl 8.5.

There was briefly an attempt made in the Tcl 8.4.12 release to detect the same brokenness and rather than error out, to log a warning about the situation using tclLog. Several bug reports filed in response to this attempt indicated that even a warning was too disruptive a change in a patchlevel release, and the warning was reverted in Tcl 8.4.13.

Finding out where a package comes from

package ifneeded can be used to find out where exactly a package is loaded form, i.e. from which file and folder. Sometimes, you may have various versions of the same package or even the same version living in different folders. Then, it can be handy to know which file actually is used. For this, you just package require the package, note the reported version number and use this in a subsequent call to package ifneeded (omitting the optional ?script? argument):

> package require abc
1.3
> package ifneeded abc 1.3
source ~/Library/Tcl/abc/abc_init.tcl

This will tell you the complete path of the loaded package file!


See also: