http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/package.htm In response to a question about finding out versions of Tcl or Expect, [Don Porter] writes: brentnye wrote: > There is a tcl command to find the version of tcl, i.e. > info tclversion Ick. Don't use that. And don't use the even worse $::tcl_version. Use [[package provide Tcl]]. Several people have asked why I recommend [[package provide Tcl]] rather than [[package require Tcl]]. In the particular example of the Tcl package, it really doesn't matter, because the Tcl package is (practically) always provided. However, I wanted the example to generalize cleanly to other packages. [[package provide foo]] and [[package require foo]] differ in how they react when no ''foo'' package is currently in the interpreter. [[package provide foo]] returns an empty string, indicating no version of ''foo'' is provided. [[package require foo]], however, tries to go find the package ''foo'' and bring it into the interpreter. This is no longer introspection, but an action. Also, if [[package require foo]] fails to find ''foo'' among the installed packages, it will raise an error. The better choice for simple introspection is [[package provide foo]]. To add yet another wrinkle, [[package present foo]] occupies a middle ground. Unlike [[package require foo]], it will not attempt to load ''foo'', but like [[package require foo]], it will raise an error if no package ''foo'' is provided in the interp. I still prefer [[package provide foo]] for introspection because I don't have to [[catch]] it. (Although I do have to be careful about passing its return value to another command expecting a version number.) ---- How would one find the source to the package one is using? [Don Porter] offers namespace eval ::myIcons { # ... variable home [file join [pwd] [file dirname [info script]]] # ... } # ... proc ::myIcons::getPath {} { variable home return $home } '''DGP''' -- Hmmmm... since someone bothered to record that advice for Wiki posterity, I should add that this is nothing more than an updated version of the advice found in library(n) and tclvars(n) that each package should define a global variable ''${package}_library'' analogous to ''tcl_library'' and ''tk_library'' storing the directory in which that package is installed. That original advice came before [namespace], back in the bad old days when the only persistent variables that could be defined were global variables. (``Persistent'' in the sense that they live longer than the execution of one [proc].) Nowadays, we clearly shouldn't be defining global variables when a namespace variable will do. Also, I've moved away from a variable named ''library'' because I find that word is used to just mean way too many different things. It's just too confusing. ---- [[Is there no succinct reference that explains the crucial role of pkgIndex.tcl?!? [CL] will return to this, if no one else does.]] '''DGP''' --- The man page for pkg_mkIndex, http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/pkgMkIndex.htm covers the basics in the HOW IT WORKS section. [[Good point.]] It's crucial that package authors understand pkgIndex.tcl as a keyword in package preparation. '''DGP''' --- For now, yes, but stay tuned for better ideas. We don't want to be chained to pkgIndex.tcl files forever. ---- [[One summary statement: package use currently requires comprehension of pkgIndex.tcl (see [Magic names]).]] ---- Don Porter advises, "Anyone writing packages should read [Will Duquette]'s tutorial on 'Namespaces and Packages' [http://www.wjduquette.com/tcl/namespaces.html] first." Also, note that Don made a presentation on how package unknown works and you can find the slides at [http://math.nist.gov/~DPorter/tcltk/oscon/]. ---- [[Distinguish package users and authors.]] ---- [Tcl syntax help] - [Category Command]