info script ?filename? returns or sets the name of the file containing the script currently being evaluated.
If the script currently being evaluated was read from a file, i.e. a call to Tcl_EvalFile() is active or source is active somewhere up the current call stack, info script returns the name of that file. info script returns the empty string if no evaluated script at any level was read from a file.
If filename is given, then for the remainder of the evaluation of the current script, info script returns that value. It is useful in virtual filesystem applictions to set a new value of info script.
info script is used, for example, to source other scripts it depends on. For example:
source [file join [file dirname [info script]] tkcon.tcl]
To be sure no symbolic links are leading to an unexpected file, use a more verbose variant:
source [file join [file dirname [file dirname [file normalize [file join [info script] ...]]]] tkcon.tcl]
MJL: I find the description from the manual page rather confusing and poorly worded. So here's my attempt at an explanation:
Every Tcl interpreter has an associated "script file" Tcl object, which is initially empty. This can be set by invoking info script new_value and retrieved by invoking info script. The function Tcl_FSEvalFile(), which is called by the source command, modifies the script file object as follows: The current value is saved, then set to the name of the file to be evaluated. The file's contents are evaluated, and then the saved value is restored.
P.S. Note that Tcl_EvalFile() is obsolete.
Moreover, as dburns noted in the Chatroom, "I believe info script is what you want, but the command must be executed before source finishes reading in the script...hence the info script must be executed at the top-level within the script file...if embedded in a proc within the script, it's 'too late' by the time the proc is run for 'info script' to work correctly"
schlenk 2005-04-24: The man page implies that it is impossible to get the filename a proc comes from after Tcl_FSEvalFile() or source has returned. So the only way to do it is to register this info while creating the proc or to use something like grep to look for it inside the filesystem.
# move the old proc command out of the way rename proc ::tcl::proc # create a replacement proc that registers all occurrences of proc creation # into the global proc_to_filename_map variable ::tcl::proc proc args { global proc_to_filename_map set proc_to_filename_map([lindex $args 0]) [info script] uplevel 1 [linsert $args 0 ::tcl::proc] }
With this one can easily find the file for a proc by looking into the array. For Tcl 8.4 and later one could use execution traces on the proc command to do the same thing without renaming proc, implementation is left as an exercise.