Sometimes it's convenient to use an existing [tcl modules%|%Tcl module%|%] file as a starting point for a new one, or to quickly change a version number for testing. Following the general principal of programming that roughly says 'where practical, define things once and only once', below is a basic template for a Tcl .tm file which allows you to change the package name and associated namespace, as well as the version number, simply by renaming the .tm file itself. As per the standard Tcl module naming convention, save as a file with a name in the format -.tm e.g ''mymodule-1.0.tm'' When placed in one of the folders in your 'module path' (see result of command ::tcl::tm::list) 'package require mymodule' will now automatically provide the module with version number 1.0 with your functions under the namespace ::mymodule namespace eval pkgtemp { set modver [file root [file tail [info script]]] lassign [split $modver -] ::pkgtemp::ns ::pkgtemp::version } package provide $::pkgtemp::ns [namespace eval $::pkgtemp::ns { variable version $::pkgtemp::version #initialise your module's namespace here (or in the next namespace eval block if desired) set version ;#this statement must be the last line in this block (version number is returned to the 'package provide' statement) }] namespace eval $::pkgtemp::ns { #module procs here } namespace delete pkgtemp The temporary namespace pkgtemp seems pretty unlikely to collide with existing namespaces - and is simply there to avoid polluting/overwriting any variables an application may have in the global namespace. ---- [Lars H]: Isn't it a principle for modules that filename hierarchy is reflected in package name and package namespace? For example the `foo::bar` package version 1.0 is in a file `foo/bar-1.0.tm` relative to a directory on the module search path. The above code would just use `bar` as package name and namespace. For avoiding global variables, one can also use [apply]: apply {code { set modver [file root [file tail [info script]]] lassign [split $modver -] ns version package provide $ns $version namespace eval $ns $code } ::} { # Module procs here, where current namespace is that of the module. # Package version can, if needed, be accessed as [uplevel 1 {set version}] } [JMN] Thanks - That's a good point about module hierarchies. I have most of mine directly on the module path - but it should be possible to adjust the template code to work out how far down the hierarchy the .tm file is. I'm less sure about apply in this situation - as one of the goals was to avoid hardcoding any namespaces in the '# Module procs here' section.. but perhaps it can be worked in. [Lars H]: Note the [namespace eval] being applied to $code! A [proc] in the code argument (the "block" that begins "# Module procs here...") will thus create a command in the namespace derived from the file name (and [variable] will create a variable there), exactly as in the first template. [JMN] Aha.. I completely misread this code. Cheers - this is nicer than creating and deleting a namespace. Here is an attempt at automatically handling arbitrary hierarchies of module namespaces. The code is now a bit unwieldy for a template.. It's almost a case for an additional helper function or two within the tcl::tm::path ensemble e.g something like: 'tcl::tm::path which ''?tm_path''' apply {code { set mypath [file dirname [file normalize [info script]]] set mysegs [file split $mypath] set overhang [list] foreach libpath [tcl::tm::list] { set libsegs [file split $libpath] ;#split and rejoin with '/' because sometimes module paths may have mixed \ & / if {[file join $mysegs /] eq [file join [lrange $libsegs 0 [llength $mysegs]] /]} { #mypath is below libpath set overhang [lrange $mysegs [llength $libsegs]+1 end] break } } set modver [file root [file tail [info script]]] lassign [split $modver -] nsfinal version set ns [join [concat $overhang $nsfinal] ::] package provide $ns $version namespace eval $ns $code } ::} { # Module procs here, where current namespace is that of the module. # Package version can, if needed, be accessed as [uplevel 1 {set version}] } ---- See also * [tm] ---- !!!!!! %| [Category Deployment] | [Category Repository] | [Category Distribution] |% !!!!!!