'''[package forget]''' ''?package package ...?'' '''[package ifneeded]''' ''package version ?script?'' '''[package names]''' '''[package present]''' ''?-'''''exact'''''? package ?version?'' '''[package provide]''' ''package ?version?'' '''[package require]''' ''?-'''''exact'''''? package ?version?'' '''[package unknown]''' ''?command?'' '''[package vcompare]''' ''version1 version2'' '''[package versions]''' ''package'' '''[package vsatisfies]''' ''version1 version2'' ---- http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/package.htm See [pkg_mkIndex] for information on things you should know about building a package (as well as information about what ''package'' is going to do to locate the package. See also [A simple package example], [extension]. [Just getting a package found already]. ---- 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. ''[MGS] 2004/02/10'' - In my packages I create a namespace array variable called ''pkginfo'' which contains values for ''package'', ''version'', ''script'', ''directory'', ''name'', ''description'', ''author'', ''email'', ''date'', ''copyright'', etc. Perhaps a '''package source''' command could be useful here (to return the directory in which the requested package's [pkgIndex.tcl] file is/was found) ? [LV] 2007 Nov 16 - it would seem to me that having some code (in my opinion as part of the core) to which best practices could refer would be ideal. Then it becomes a matter of going from package to package, suggesting that maintainers add a line to their package to register the appropriate information. ---- [[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. See also [pkg_mkIndex pitfalls]. ---- [[One summary statement: package use currently requires comprehension of pkgIndex.tcl (see [Magic names]).]] ---- Don Porter advises, "Anyone writing packages should read [William 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/]. A current version of the work appears at http://math.nist.gov/~DPorter/tcltk/package/ . ---- [[Distinguish package users and authors.]] ---- Don writes, "The main weakness is that the [[package]] system does not keep track of what the interdependencies are. We get "can't find package foo" instead of 'could not load package foo 1.3 because it depends on bar 2.1, and that is not installed'." CL agrees with this, and complains that package authorship is clumsy and error-prone. Perhaps more on this subject will appear in October 2001. [LV] Another common encounter is getting "can't find" and the cause is that the directory in which it was installed isn't on $auto_path , or perhaps the pkgIndex.tcl contains code that just doesn't work. In fact, I've seen cases where syntax code in one package's pkgIndex.tcl caused tcl problems when some other package was required.... ---- [Using Tk as a loadable package] ---- [JCW] was once heard to conclude, ''Package require is a contract to make a certain API available, not a procedural-call-with-side-effects in disguise - IMNSHO.'' ---- See also '''On Namespaces And Packages''' [http://www.wjduquette.com/tcl/namespaces.html] and '''Programmation modulaire en Tcl/Tk''' [http://www.larochelle-innovation.com/tcltk/207]. ---- '''List of currently loaded packages:''' proc packages {} { # returns the list of presently loaded packages set res {} foreach i [package names] { if {[string length [package provide $i]]} { lappend res $i } } set res } ;# RS [LV] Is there a way to modify this packages proc so that it also reports the version of the package that was loaded? [Lars H]: Yes, simply change the lappend res $i line to lappend res $i [package provide $i] ---- Started a new page on [package equivalences] to sort out issues regarding packages which need to co-exist, such as binaries with a fallback to a pure Tcl implementation. -[jcw] ---- See also [Tcl modules] for possibly new alternatives to packages. Then there is [kitten], which is an example of storing packages in a single [starkit] which is easier to ship around. ---- [RS] 2006-01-29: Here's a package version retriever that returns a list, which can be put into a [dict] or [array]: proc packages {{pattern *}} { catch {package require ""} set res {} foreach p [lsort [package names]] { if [string match $pattern $p] { lappend res $p [package versions $p] } } set res } Incidentally, packages [Tcl] and [ActiveTcl] report {} at [package versions], seen on 8.4.5 and 8.4.12. At least the former could do the same as what [info patchlevel] does... [Tk] says 8.4 at least, but there are many precedents of packaging reporting 3-part version numbers, [Mk4tcl] even does four: 2.4.9.2. Test: % foreach {p v} [packages T*] {puts "$p : $v"} Tcl : TclScript : 1.0 Tclx : 8.4 Tk : 8.4 Tkhtml : 2.0 Tktable : 2.8 Tkx : 8.3 Trf : 2.1 ---- "[Where does the package command find the packages it seeks?]" ---- [LV] 2007 August 30 Is it possible at this time to distribute a Tcl package as a single [starkit], and have that single file be recognized by a developer/user's code? If so, what steps would the package developer need to follow, and what steps would the receiver of the starkit have to follow, for this to work? ---- [hat0] If you're looking for a useful guide to making packages for your own system or distribution, the Tcl tutorial has an excellent step-by-step guide to the process here: http://www.tcl.tk/man/tcl8.5/tutorial/Tcl31.html ---- See also * [package management] ---- !!!!!! %| [Tcl syntax help] | [Category Command] | [Category Package] |% !!!!!!