Updated 2018-08-24 15:06:37 by pooryorick

package present ?-exact? package ?version?

"This command is equivalent to package require except that it does not try and load the package if it is not already loaded." Its canonical description appears in the man page [1].

etdxc Sorry for being so literal, but I presume this means that it tries to load the package only when it is not already loaded.

CL agrees that the man page is unsatisfying. I submit this alternative:

  • If package is loaded, the command returns its version;
  • If package is not loaded, the command branches to error "package $package not present".

LV Here's an example:
 $ tclsh
 % package names
 Tcl
 % package present Tk
 package Tk is not present
 % package require Tk
 8.5
 % package present Tk
 8.5

DGP has been heard to say, "the one place I find [package present] useful as defined is in the script portion of a package that has both C and script portions. I have the C initialization call Tcl_PkgProvide(), and the script part does [package present -exact Foo 1.2.3] to verify it got loaded in a C part from the same release. [This] reports possible install errors."

To use [package present] in a script, it is useful to enclose it in a catch:
 proc is_Tk_present {} {
   expr ![catch {package present Tk}]
 }

CecilWesterhof: I created a more general proc in a package. This way you can use it also in an interactive shell:
proc ::dcblUtilities::isPackagePresent {package} {
    expr {![catch {package present $package}]}
}

By the way, sometimes there is a 'better' way. For example to know if Tk is loaded you could use:
info exists tk_version

EF This means that if you want to (dynamically) know all the packages that a script has loaded in, you can do the following:
    foreach n [package names] {
        if { ! [catch {package present $n} v] } {
            puts $n
        }
    }

DKF: Maybe this would be simpler (and more useful, since it prints the version number too):
 foreach n [lsort -dictionary [package names]] {
    catch {puts "$n [package present $n]"}
 }

LV Today, I was discussing with AK this situation - if an application developer attempts to load tdom and tclxml (I think those are the two), the result is a crash in the application (because of some kind of conflict in the external symbols used). So I was musing that what probably there should be some way to indicate, in a package, not to load a package if some other package was loaded. AK mentioned that package present would probably be the way to go to develop such a thing...

See also: