I want to know about modular programming in tcl and how we can achieve that .
In some tcl tutorials mention like source command having some drawbacks in achieving "modularity" so that we came to the "package" after that "package" is having some more drawbacks so that we came with the combination of package and namespaces .
I want to know what are the drawbacks and proper hierarchy of 3 concepts . Can Anyone help me ?
I'm not sure if I understand your question correctly, so I'll try to explain the 3 commands you throwed in your question:
source: Evaluates a file as a Tcl script. -
It simply opens the file, reads until the EOF character (^Z on both windows and *nix) and evaluates it.
It does not keep track of sourced files, so you can source the same file again (great for hotpatching), but this is the drawback: It will source the file again.
package: Manages packages. It basically keeps track of the provided packages and tries to figure out which file it has to source to load a new package.
namespace: They provide context for commands and variables, so you don't have to worry about unique names for your commands. Just the namespace has to be unique. Has nothing to do with loading packages or other modules, it just provides namespaces.
I suggest that you use packages, each package in it's own file, each package with a namespace equal to the package name where all commands reside.
You should export the public commands with namespace export.
Related
I think this is more of a Tcl configuration question rather than a Tcl coding question...
I inherited a whole series of Tcl scripts that are used within a simulation tool that my company built in-house. In my scripts, I'm finding numerous instances where there are function calls to functions that don't seem to be declared anywhere. How can I trace the path to these phantom functions?
For example, rather than use source, someone build a custom include function that they named INCLUDE. Tclsh obviously balks when I try to run it there, but with my simulation software, it runs fine.
I've tried grep-ing through the entire simulation software for INCLUDE, but I'm not having any luck. Are there any other obvious locations outside the simulation software where a Tcl function might be defined?
The possibilities:
Within your software. (you have checked for this).
Within some other package included by the software.
Check and see if the environment variable TCLLIBPATH is set.
Also check and see if the simulation software sets TCLLIBPATH.
This will be a list of directories to search for Tcl packages, and you
will need to search the packages that are located outside of the
main source tree.
Another possibility is that the locations are specified in the pkgIndex.tcl file.
Check any pkgIndex.tcl files and look for locations outside the main source tree.
Within an unknown command handler. This could be in
your software or within some other package. You should be able to find
some code that processes the INCLUDE statement.
Within a binary package. These are shared libraries that are loaded
by Tcl. If this is the case, there should be some C code used to
build the shared library that can be searched.
Since you say there are numerous instances of unknown functions, my first
guess is that you have
not found all the directories where packages are loaded from. But an
''unknown'' command handler is also a possibility.
Edit:
One more possibility I forgot. Check and see if your software sets the auto_path variable. Check any directories added to the auto_path for
other packages.
This isn't a great answer for you, but I suspect it is the best you're going to get...
The procedure could be defined in a great many places. Your best bet for finding it is to use a tool like findstr (on Windows) or grep -R (on POSIX platforms) to search across all the relevant source files. But that still might not help! It might not be a procedure but instead a general command, which could be implemented in C and not as a procedure, or it could be defined in a packaged application archive (which are usually awkward to look inside). There are also other types of script-implemented command too, which could make things awkward. Generally searching and investigating is your best bet, but it might not work.
Tcl doesn't really differentiate strongly between different types of command except in some introspection operations. If you're lucky, you could find that info body tells you the definition of the procedure (and info args and info default tell you about the arguments) but that won't help with other command types at all. Tcl 8.7 will include a command (info cmdtype) that would help a lot with narrowing down what to do next, but that's no use to you now and it definitely doesn't exist in older versions.
I started to write some Tcl Lines in Atom, but the Script package I use isn't able to run Tcl.
Does anybody know other packages, or plug ins to solve my problem?
Have you considered submitting a pull request for Tcl? Adding support for new languages is quite easy, all you have to do is edit grammars.coffee.
Support for Tcl was just merged into the atom-script package and should be part of the next release.
Otherwise, have a look at the build package plus the build-tclsh provider. Alternatively, the package lets you specify a custom build configuration as JSON/CSON/YAML.
I have a strange problem I am using fedora 20 and installed tcllib on my system.
But if I use package require uri in example I got an package not found in response.
Does anyone know what the issue here is or how to determine if the tcllib is added in the package index?
Tcl looks up packages in two ways: with auto_path and with tcl::tm::path.
1. The auto_path — the traditional mechanism.
When you do package require, the package manager looks to see if the package is already present, or if instructions for obtaining the package from the filesystem are present. If neither of these is true, it asks the package unknown handler to load it (strictly, it's the handler installed using the package unknown command). The default implementation of that handler loads packages by looking for pkgIndex.tcl files in the directories on your auto_path, and their immediate subdirectories.
auto_path is a global variable holding a Tcl list of directories to search. You can probably just lappend the right place to it. pkgIndex.tcl is a Tcl script that describes how to make the package available, which it does by calling an appropriate package ifneeded command. The actual loading of the
Once a package is required that isn't present but its instructions for obtaining are, Tcl will simply eval those instructions: they're just a plain old script (that usually just calls source and/or load to do the grunt work).
2. Tcl modules — the new (in 8.5) mechanism.
The Tcl module system uses a different search system managed with the tcl::tm::path command. The tcl::tm::path list subcommand will tell you where it looks (a huge list, to be honest) and you can use the tcl::tm::path add subcommand to extend the path with extra locations to search. Tcl modules have the entire package placed into a single file (with the extension .tm) and have a structured name so that they can avoid having a separate pkgIndex.tcl file; the TM loader can synthesise the package ifneeded calls from the filename itself (in all cases, this is done with source; there are some clever ways to package binary code inside files so they can be loaded, but they're far outside the scope of this answer).
At that point, you're back to the source of the file when the package is actually required; that part is the same whether you're using a module or a traditional package.
The module system is much faster than the traditional search mechanism since it doesn't need to open any files to figure out what to do: it just uses glob with the right options. It is, however, less flexible in how things can be packaged: multi-file packages (e.g., almost anything you make yourself) can't be made into modules (well, not without extra work).
Can anyone explain me what is the use of init.tcl?
When actually it is loaded by the TCL interpreter?
The description for this file is shown as
startup file for TCL .
But According to my knowledge .tclshrc is the start up file.
Can anyone explain this?
Actually, init.tcl is the first file that is loaded by a Tcl_Interp*.
Its job is to setup the different package loading mechanisms.
Some programs, most notably tclsh, will source the .tclshrc. This is usually done using Tcl_SourceRCFile.
So init.tcl is sourced for every Tcl interpreter, while the .tclshrc is only sourced by some programs that explicitly do that.
* does not apply to safe interpreters
This question already has an answer here:
TCL : Regarding source , package , namespace command
(1 answer)
Closed 8 years ago.
The source command reads the file content and executes it line by line.
Packages also internally uses source command.
Somebody says that source command having the drawbacks, my question is the same drawbacks won't come when we are using the package (package require) command.
I analysed alot on this, but i did not get full clarification regarding this.
I want to know the following things:
What are the drawbacks of source command?
Why we come for packages?
What are the drawbacks of package?
Why we go for Namespace?
Packages are higher-level concepts than source files; when you do package require that gets converted internally into a source of the appropriate file (or files) that implements the package. It might also load a shared library that was implemented in C, and other more complicated options are possible. You don't have to know what it is doing.
Namespaces are orthogonal, in that they don't map at all to source files. They're just script-visible things for defining a mapping from names to entitles (commands, variables, …)
By convention, packages should use a namespace with the same name as the package's name; this is not universally followed (and nobody is about to change that; many existing packages predate the namespace mechanism and breaking them just to enforce the convention would be very user-hostile). You are encouraged to follow the convention as it is a useful way to simplify things; it makes things easier for users of your code.