As far as I know, the source command only accepts the name of the script. Is there any workaround to source a script with any number of arguments?
set argv [list your parameters go here]
source myscript.tcl
Related
How can I access the variable which got set while executing a TCL program from a terminal? Please help.
Regards,
Sagar
If you're referring to running a script with tclsh from a prompt, just have the script write a temp file containing the value of the variable. I interpreted your question as, how do I preserve the variables value after the script end, but could be way off base there
I have seen a topic regarding to how we plot graphs with Gnuplot in Tk Canvas. Here are the simple code sample from Donal Fellows#Donal Fellows. Can someone help me on these two commands in Bold(set term tk;gnuplot .c)? I can not understand what does it mean.Thanks.
package require Tk
eval [exec gnuplot << "
**set term tk**
plot x*x
"]
pack [canvas .c]
**gnuplot .c**
When you run the gnuplot program with the terminal set to tk, it writes to its standard output a Tcl script that will create a procedure. That procedure is called gnuplot, and it takes a single argument which is the name of the canvas to plot onto. So we call the gnuplot program with the appropriate arguments to get it to tell you how to make a command that will actually do the plotting. We eval that result, make the canvas, and delegate to that newly-created gnuplot command the actual plotting on the canvas.
It's a little odd, and theoretically unsafe (what if the gnuplot is hacked?!?!?! Oh noes!) but actually works quite well in practice.
To see why it works, try doing:
puts [exec gnuplot << "
set term tk
plot x*x
"]
Instead of evaluating the code, that will print it out. You'll see that it's a procedure definition, and how exactly it all works. (Alas, I've not got gnuplot installed on this computer at the moment, so I can't do the check quite instantly for you…)
I'm not an expert of gnuplot, but as far as understand the 2 command are very simple.
set term tk
Assign the value string tk to the variable term.
gnuplot .c
Launch the command gnuplot with argument .c.
In your code the .c is just the name of the tk canvas widget.
More intriguing is the first [exec gnuplot <<...] that execute an external command called gnuplot that initialize the tk script and define the tk command gnuplot used to draw the plot on a canvas.
It looks like the external gnuplot command generate the tck code to define all what is needed.
Sometimes its needed to get current path of a script. What are the ways to do that?
While a script is being evaluated (but not necessarily while its procedures are being called) the current script name (strictly, whatever was passed to source or the C API equivalent, Tcl_EvalFile() and related) is the result of info script; it's highly advisable to normalise that to an absolute pathname so that any calls to cd don't change the interpretation.
Scripts that need the information tend to put something like this inside themselves:
# This is a *good* use of [variable]…
variable myLocation [file normalize [info script]]
They can then retrieve the value (or things derived from it) easily:
proc getResourceDirectory {} {
variable myLocation
return [file dirname $myLocation]
}
The other common locations are:
$::argv0 which is the “main” script (and you're evaluating the main script if it's equal to info script)
[info nameofexecutable] which is the Tcl interpreter program itself (typically the argv[0] at the C level)
[info library] which is where Tcl's own library scripts are located
$::tcl_pkgPath which is a Tcl list of directories where packages are installed
$::auto_path which is a Tcl list of directories where scripts are searched for (including packages! The package path is used to initialise this.)
The best way I found to do that:
set script_path [ file dirname [ file normalize [ info script ] ] ]
puts $script_path
You may also try like this:
file normalize $argv0
file normalize [info nameofexecutable]
to get fully normalized name
You might have a look at http://wiki.tcl.tk/1710. The solution there also takes care of possible (multiple) symbolic links and points to the physical root location of the script.
In case it does not work with "info script", you can do
regsub {/[a-zA-Z0-9_]+$} $argv0 {} path
do $path/other_script_on_the_same_path_as_this.tcl
Now you will have the path of the current script on the variable $path.
I have a tcl script drakon_gen.tcl . I am running it, from another script run.tcl like this:
source "d:\\del 3\\drakon_editor1.22\\drakon_gen.tcl"
When I run run.tcl I have following output:
This utility generates code from a .drn file.
Usage: tclsh8.5 drakon_gen.tcl <options>
Options:
-in <filename> The input filename.
-out <dir> The output directory. Optional.
Now I need to add to run.tcl options that are in the output. I tried many ways but I receive errors. What is the right way to add options?
When you source a script into a tcl interpreter, you are evaluating the script file in the context of the current interpreter. If it was written to be a standalone program you may run into problems with conflicting variables and procedures in the global namespace. One way to avoid that is to investigate the use of slave interpreters (see the interp command) to provide a separate environment for the child script.
In your specific example it looks like you just need to provide some command line arguments. These are normally provided by the argv variable which holds a list of all the command line arguments. If you define this list before sourcing the script you can feed it the required command line. eg:
set original_argv $argv
set argv [list "--optionname" "value"]
source $additional_script_filename
set argv $original_argv
I am having a little problem understanding the following command:
package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]]
in the pkgIndex.tcl,
I understand that when the pkgIndex.tcl is sourced and for example, we package require HelloWorld 1.0 , the helloworld.tcl will be sourced. I dont understand the list command...
The package ifneeded command is used to register (or query) how to make a package actually become present in a Tcl interpreter. This is done by evaluating a script, which is the argument generated with list in your example. Let's deconstruct it.
package ifneeded HelloWorld 1.0 [list source [file join $dir helloworld.tcl]]
---------------- ========== --- =============================================
command name package ver how to make it present,
name result of [list ...]
So far, so good. Now, a little aside: the list command is not just used for making lists, but it also makes guaranteed-substitution-free commands. That is, its result is a scrip that consists of an invocation of the command with its arguments, exactly as they were when they went into the list command.
This means that we're producing a script that is source somefilename, where somefilename is the result of the file join. In other words, you're getting almost the same thing as:
package ifneeded HelloWorld 1.0 "source $dir/helloworld.tcl"
Except that there is no assumption that the filename separator is / (that's formally a feature of the OS, not of Tcl, and file join knows about the difference) and it is safe if $dir happens to contain a space or other metacharacters (rather more common than you might hope).
What is $dir? Well, it's a special feature of pkgIndex.tcl scripts that they are (normally) evaluated in a context that sets the dir variable to the absolute name of the directory that contains the pkgIndex.tcl script. (You mustn't make assumptions about the current directory at this point; that belongs to the user of the main Tcl program, not to the package author.) This makes it enormously easier to relocate a package, as you can place all its component files relative to the one script and just move the whole lot in one chunk.
The package ifneeded command expects the following inputs:
package ifneeded package version ?script?
You can see that in your case, the package is HelloWorld, and the version is 1.0. Finally, the script is [list source [file join $dir helloworld.tcl]]. The reason list is used is that the script parameter expects a list.
The package ifneeded command expects a script as its last argument. A script is expected (in a common sense) to be well-formed, that is, to be parsable by the Tcl parser.
In this case of a rather standard pkgIndex.tcl, the thing to ensure is: no matter what the "dir" variable contains at the time the code from that pkgIndex.tcl is processed, the script should be constructed in such a way, that later the Tcl parser sees in it the source command with exactly one argument — no matter if $dir expanded to contain whitespace or funky characters like { etc.
Enter the list command. Here, it's used to construct a list of two elements: the string "source" and a string containing a file name (to serve as the sole argument to that source command). Now, when that list is interpreted as a script (a string), Tcl ensures that string representation contains all the needed quoting to remove any ambiguity about whitespace etc.
This ensures when the parser later interprets our constructed script, the source command in it will receive exactly one argument.
You can read much more of better written information on using list to prevent quoting issues here.