See Don Porter's 2001 Tcl Conference presentation:
http://math.nist.gov/~DPorter/tcltk/oscon/
Don Porter http://math.nist.gov/~DPorter/tcltk/
Mathematical & Computational Sciences Division Information Technology Laboratory National Institute of Standards and Technology Gaithersburg, Maryland
Naive answer: Grey.
pack [button .b -text Example]
True answer: What ever color you want.
pack [button .b -text Example -bg red]
Grey is merely the default.
Naive answer: Uses $::auto path as a search path... Looks for pkgIndex.tcl files created by pkg_mkIndex, source's them, etc. ...
True answer: However you choose!
Why don't people know this? Why don't people use this?
Define provide script and index script
Three parties involved in package management
Defacto interface: tclPkgUnknown - Features and Limitations
Propose: New customization hook package fsindex - Sysadmin control over how packages are installed
A package starts as a collection of related Tcl commands, namespaces, and/or variables grouped together as a single unit.
Grouping simplifies loading and introspection.
Collection becomes a package by calling package provide
namespace eval :: { package provide hw 1.0 namespace eval hw { namespace export hello; variable Who world proc hello {} { variable Who; puts "Hello, $Who!" } } }
Load package into interp: eval provide script
Evaluation of provide script must call Tcl_PkgProvide()
Simplest possible provide scripts:
set pscript1 {package provide hw 1.0} set pscript2 {package provide hw 2.0}
Exactly one version of each package per interp:
namespace eval :: $pscript1 namespace eval :: $pscript2 -> conflicting versions provided for package "hw": 1.0, then 2.0
Authors register provide scripts with package ifneeded
package ifneeded hw 1.0 {package provide hw 1.0} package ifneeded hw 1.1 {package provide hw 1.1} package ifneeded hw 2.0 {package provide hw 2.0}
Users call package require to select and eval one registered provide script
package require hw 1 -> 1.1
Explains how provide scripts are evaluated.
How are package ifneeded commands evaluated?
Authors provide an 'index script' for each package
Index script includes package ifneeded - Just as provide script includes package provide
Simplest possible index script:
set iscript {package ifneeded hw 1.0 {package provide hw 1.0}}
User needs evaluation of index script
eval $iscript
Mechanism? package unknown !
User calls package require
package require $package $requiredVersion
When no registered provide script will satisfy the requirement, package require evaluates:
namespace eval :: [package unknown] [list $package $requiredVersion]
package unknown returns command to be used for finding and evaluating index scripts.
package unknown -> tclPkgUnknown
Why not call tclPkgUnknown directly? - package unknown enables customization
package unknown ?command?
User can select any command for finding and evaluating index scripts.
proc falseWitness {p v args} { package ifneeded $p $v [list package provide $p $v] } package unknown falseWitness
Opens up many possibilities...for the user .
An installed package has its provide script in a file.
$ cat /usr/lib/hw1.0/hw.tcl -> package provide hw 1.0
Scripts registered with package ifneeded refer to files
package ifneeded hw 1.0 {source /usr/lib/hw1.0/hw.tcl} package ifneeded foo 2.0 {load /usr/lib/foo2.0/../libfoo2.0.so}
But the sysadmin, not the author, decides the installation directory for the package!
The provide script needs to know the installation directory. - Unknown to the author who would write provide script.
Index script has job of registering provide script.
Give index script job of creating provide script too!
package ifneeded hw 1.0 [list source [file join $dir hw.tcl]] package ifneeded foo 2.0 [list load [file join $dir .. libfoo2.0.so]]
Interface requirement: index script evaluated incontext where $dir is the installation directory.
Called with arguments '$package' and '$requiredVersion'
Treats $::auto_path as an input
Evaluates the pkgIndex.tcl files
Ignores arguments telling what to search for
Errors in index scripts of all installed packages reported. Even in packages that are never used
Keeps no map to be more selective.
Shares $::auto_path with the auto-loader
Only one pkgIndex.tcl file per directory.
No installed package introspection.
So why not use package unknown to replace tclPkgUnknown with something better?
Can package unknown allow sysadmins to customize the way in which packages are installed on their systems?
Not alone.
package unknown only solves half the problem.
No customizable interface for storing index scripts
Once packages are installed as tclPkgUnknown expects, no other retrieval routine can do better.
Need another customization hook in package
Allow sysadmins to customize package installation conventions on their filesystems.
... like [package unknown]
Preserve an unchanging interface to authors writing package installation routines.
... like [package require]
The customizable interface to the collection ofi ndex scripts stored in the filesystem.
Customization just like package unknown
package fsindex ?command?
package fsindex with no arguments -Returns the command that manages index scripts on the filesystem
package fsindex $command - Registers $command as the command that manages index scripts on the filesystem
Responsibility of sysadmin to register package fsindex command matching package installation convention ofthe filesystem.
For each installed package, the command registered with package fsindex must keep track of
provides access to this information through an interface of several subcommands.
namespace eval :: { [package fsindex] $subcommand $args }
For simplicity, assume package fsindex foo.
Implements the package unknown function.
foo satisfy $package $version
* Finds all index scripts for all versions of package $package that might satisfy the $version requirement * Limit search to search path set by foo searchpath * Evaluate all found index scripts in search path order, set $dir
New default package unknown
proc default {args} { uplevel 1 [package fsindex] satisfy $args } package unknown default
Limit packages searched by installation directory.
Three forms:
Generalizes setting of $::auto path
Add new index script tothe system
foo insert $p $v $d $indexScript
Part of package installation
Called after files of version $v of package $p have been installed into installation directory $d
Registers its $indexScript
Generalization of part of pkg_mkIndex
Remove index script from the system
foo delete $p $v $d
Part of package uninstallation
Called after files of version $v of package $p have been removed from installation directory $d
Generalization of deleting pkgIndex.tcl file
What packages are installed, where?
foo names foo versions $p foo directories $p $v
provides what users want from package names
Can use with foo searchpath to carefully limit search to just the directories needed.
Coming Soon: the package fsidb
Simple implementation of the package fsindex interface
Collection of index scripts and installation directories associated with packages kept as simple Tcl array read in from a single file.
Add package fsindex
Wrap (parts of) package fsindex interface around existing tclPkgUnknown .
Initialize package unknown with default that uses package fsindex toquery installed packages.
Migrate package installation scripts to use new installation interface - Installer packages and tools?
Still one hook missing to allow use of fsidb, etc. ...
Installed packages available for any Tcl interp -tclsh -wish -embedded interps
Index scripts are stored how they're stored.
Could "hack" the init.tcl file
...or init.tcl could explicitly eval a system customization file. (Feature Request 219375. Patch 403526.)
A straightforward extension of package offers