Reputation: 381
I'm a beginner on tcl/itcl and I'm trying to create a package.
The problem is that my files inside the package are dependent one on each other.
For example:
pkgIndex.tcl
package ifneeded test 1.0 [list ::apply {dir {
package require Itcl
namespace eval ::test {
namespace export *
variable version 1.0
}
source [file join $dir system.itcl]
source [file join $dir subsystem.itcl]
package provide test 1.0
}} $dir]
system.itcl
itcl::class ::test::system {
...
private variable _subsystems ""
...
constructor {} { lappend _subsystems [::test::subsystem #auto] }
...
}
subsystem.itcl
itcl::class ::test::subsystem {
...
private variable data ""
...
constructor {} { set data "new data" }
...
}
In this case, I should include subsystem.itcl file in system.itcl.
If I wasn't providing a package, I would use the source command but I read that when a package is provided you don't use source command instead there are other methods that will do the "include" operation.
The problem is that I couldn't find anywhere example / website that explain how to do it.
Upvotes: 1
Views: 563
Reputation: 13252
I would do this:
(system and subsystem aren't packages in this scenario: see below)
(DIR is a directory in or added to $auto_path
)
DIR/pkgIndex.tcl
package ifneeded test 1.0 [list source [file join $dir test.tcl]]
DIR/test.tcl
package require Itcl
set dir [file dirname [file normalize [info script]]]
source [file join $dir subsystem.itcl]
source [file join $dir system.itcl]
namespace eval ::test {
namespace export *
variable version 1.0
}
package provide test $::test::version
DIR/system.itcl
itcl::class ::test::system {
...
private variable _subsystems ""
...
constructor {} { lappend _subsystems [::test::subsystem #auto] }
...
}
DIR/subsystem.itcl
itcl::class ::test::subsystem {
...
private variable data ""
...
constructor {} { set data "new data" }
...
}
Note that I don't use Itcl, so I don't know if I'm mangling it here.
The point of doing it like this is that I would want
pkgIndex.tcl
as simple as possiblepackage require
here)main.tcl
, just separated away in their own files for neatnessmain.tcl
expressing all information on how the parts of the code connect to each otherIf system and subsystem should be packages, I would do:
(DIR is a directory in or added to [::tcl::tm::path list]
)
DIR/test-1.0.tm
package require test::system
namespace eval ::test {
namespace export *
variable version 1.0
}
DIR/test/system-1.0.tm
package require Itcl
package require test::subsystem
itcl::class ::test::system {
...
private variable _subsystems ""
...
constructor {} { lappend _subsystems [::test::subsystem #auto] }
...
}
DIR/test/subsystem-1.0.tm
package require Itcl
itcl::class ::test::subsystem {
...
private variable data ""
...
constructor {} { set data "new data" }
...
}
Note that package provide
isn't necessary here: it's done automagically when the module is loaded.
The point of doing it like this is that I would want
to avoid having to maintain an up-to-date pkgIndex.tcl
the parts as self-contained as possible
every part expressing what it needs for itself to work
Upvotes: 1
Reputation: 381
Ok. I did this in the following way and it worked.
pkgIndex.tcl
package ifneeded test 1.0 [list source [file join $dir test.tcl]]
package ifneeded system 1.0 [list source [file join $dir system.itcl]]
package ifneeded subsystem 1.0 [list source [file join $dir subsystem.itcl]]
test.tcl
package require ::test::system
namespace eval ::test {
namespace export *
variable version 1.0
}
package provide test 1.0
system.itcl
package require ::test::subsystem
package require Itcl
itcl::class ::test::system {
...
private variable _subsystems ""
...
constructor {} { lappend _subsystems [::test::subsystem #auto] }
...
}
package provide ::test::system 1.0
subsystem.itcl
package require Itcl
itcl::class ::test::subsystem {
...
private variable data ""
...
constructor {} { set data "new data" }
...
}
package provide ::test::subsystem 1.0
so every file is providing me a different package and requiring a different packages and pkgIndex file just making it to be possible by indeed command.
Upvotes: 0