Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Howcan I create TCL Library in TCL? 2

Status
Not open for further replies.

KotiChennayya

Programmer
Oct 3, 2003
15
0
0
IN
Hi All,
Can I create a TCL library in TCL itself?Yep in C its possible.But isthere any way to do it in TCL itself?
Thanks & rgds
Koti
 
The source command works fine for pulling a couple of auxiliary Tcl script files into a main Tcl application, or for loading Tcl libraries from a common shared area in small workgroups. But for more extensive collections or for wider distribution, you should consider instead putting together your library as a Tcl package.

The quick and dirty on creating a Tcl package is as follows:
[ol][li]Collect all the files implementing your package in a single directory.[/li]

[li]In each file, add a package provide command that "advertises" that the file provides (a piece of) a particular version of a particular package. For example:

[tt]package provide wonderlib 1.0[/tt][/li]

[li]Start an interactive tclsh or wish session.[/li]

[li]Execute the command pkg_mkIndex, providing it the directory in which your library files reside and, optionally, a glob pattern of the files you want indexed (the default is to index all files in the directory with the extension "[tt].tcl[/tt]"). For example:

[tt]pkg_mkIndex /usr/local/share/tcl/wonderlib[/tt]

This creates a file in that directory named pkgIndex.tcl, which is used by Tcl to determine what commands are provided by a package and what it needs to do to load in the package. (You can also create this file by hand, for more complex situations.)[/li][/ol]
Your package is now ready. To use it in an application, you either have to tell Tcl where your package is located, or copy your package (the contents of the library directory) to a place where Tcl automatically looks for packages.

To explicitly tell Tcl where your package is loacted, you need to append the library directory to the special global Tcl variable auto_path before you attempt to use the library in that application. For example:

Code:
lappend auto_path /usr/local/share/tcl/wonderlib

If instead you copy the library to where Tcl looks for packages automatically, you won't need the line above. The best place to put packages you create is as a subdirectory of the lib subdirectory of your Tcl installation. In other words, if you've got Tcl installed in $INSTALL, you could create a subdirectory like $INSTALL/lib/wonderlib, and then copy all of your Tcl library files (including the pkgIndex.tcl file) into that directory.

Now, to actually load the package into an application, all you need to do is:

[tt]package require wonderlib[/tt]

It might sound like a lot of steps, but it's actually quite easy to do. Once you've done your first one, you could practically do it in your sleep.

For more information about creating packages, check out the Tcl'ers Wiki ( I'd recommend starting with "package," You might also want to check out "A simple package," As well as "pkg_mkIndex pitfalls," Also, Will Duquette has an excellent document on using Tcl namespaces with packages at
- Ken Jones, President, ken@avia-training.com
Avia Training and Consulting, 866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
I have read % pkg_mkIndex d:/tcl/lib/futil *.tcl
#Until this step all is ok,there do is a pkgIndex.tcl #file,but in this file there are only "#..." lines.

% package require futil
can't find package futil

% pkg_mkIndex -verbose d:/tcl/lib/futil futil.tcl
warning: error while sourcing futil.tcl: can't read "argv0": no such variable

#why?
% source d:/tcl/lib/futil/futil.tcl
% package require futil
0.1
 
Thanks a lot to all of you.Your suggesitions really helped me a lot.
Thanks once again
Rgds
Koti
 
Very odd, Irixer. I've taken the code from exactly as shown, put it in a file on my system, and successfully generated a proper pkgIndex.tcl file. I'm not sure what the problem might be in your situation.

In general, the way pkg_mkIndex works is to load the indicated files into a child interpreter, and then figure out what commands and packages each file provides. Based on this information, pkg_mkIndex then creates the pkgIndex.tcl file, which describes what file(s) to load to obtain a particular package and version.

So, if an error occurs during this "introspection" process, I can see how pkg_mkIndex could end up creating a file with nothing but the default header comments. What confuses me is why it's encountering an error in your case. When it complains that it "can't read `argv0'", it would seem as though it's trying to access argv0 without it existing. But argv0 should exist in almost all cases, and even if it doesn't, the only place it appears in futil.tcl is in the "self-test" code, and before it does anything with the variable, it explicitly tests for its existence with info exists (though that command is abbreviated, a practice I advise against).

If you could post a copy of the stack trace you get after your pkg_mkIndex -verbose (print the contents of the global errorInfo variable), we might be able to track down the problem.

- Ken Jones, President, ken@avia-training.com
Avia Training and Consulting, 866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Here is the errorInfo,
(bin) 5 % set errorInfo
can't read "argv0": no such variable
while executing
"info ex $argv0"
(file "futil.tcl" line 1)
invoked from within
"$c eval {
set ::tcl::debug "loading or sourcing"

# we need to track command defined by each package even in
# the -direct case, because they ar..."
(bin) 6 %

Regards,
Irixer
 
After commenting the "self_test" paragraph out,

(bin) 17 %pkg_mkIndex -verbose d:/tcl/lib/futil futil.tcl
successful sourcing of futil.tcl
can't read "::tcl::direct": no such variable

(futil) 18 % set errorInfo
can't read "::tcl::direct": no such variable
while executing
"if { !$::tcl::direct } {
tclLog "commands provided were $cmds"
}"
(procedure "pkg_mkIndex" line 281)
invoked from within
"pkg_mkIndex -verbose d:/tcl/lib/futil futil.tcl"

In this step, no pkgIndex.tcl is created.

(futil) 22 % pkg_mkIndex d:/tcl/lib/futil futil.tcl
(futil) 23 % package require futil
0.1

Now the pkgIndex.tcl is ok with the line "package ifneeded futil 0.1 [list source [file join $dir futil.tcl]]"appended automatically,but I still don't know why.

Regards,
Irixer
 
Well, the first stack trace identifies the error: a simple typo. There should be no "$" in front of the "argv0" for the info exists command. The correct syntax would be (spelling the command out completely, as I strongly recommend):

Code:
info exists argv0

The second error you reported, "can't read ``::tcl::direct'': no such variable" concerns me a lot more. This is in the actual pkg_mkIndex code, which is part of the Tcl library files. Quite simply, you shouldn't be getting errors there. And when I generated the pkgIndex.tcl file in my test, I didn't receive any error messages like that. I suppose it's possible that you've encountered some bug in an older Tcl version (I tried this out with 8.4.1 and 8.4.2). But if you're running a current version of Tcl -- and there aren't any other readily identifiable factors -- it starts to make me wonder whether there was some corruption in your Tcl installation.

- Ken Jones, President, ken@avia-training.com
Avia Training and Consulting, 866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Thanks a lot! I try the command pkg_mkIndex -verbose in my Tcl8.3,it works. I agree with what you said. There do is something wrong with my tcl/tk8.4.4 installation and the reinstallment can not resolve this frustrating thing.

thanks again!
Irixer
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top