budd...@gmail.com wrote:
> Hi!
> I'm new to tcl, but I use Common Lisp (CL) for many years.
> There is one very good utility in CL IDEs I use.
> When insertion cursor is at some currently existing
> function name, I press just one hotkey and IDE opens
> a place in a source file where that function is defined.
> IDE does not grep files, it uses location information
> collected at compilation time, so this information is
> precisely exact (unless file have been edited since compilation).
> I undertaken some minimalistic search for a similar feature in tcl,
> but I was unable to find it.
> So I implemented it myself.
> Code is here:
>
https://bitbucket.org/budden/clcon/src/default/record_definition.tcl
> ...
> I'd like to hear comments on code quality.
proc showVar {name} {
puts "sV:$name=[uplevel 1 [string cat {format %s $} $name]]"
}
Do not do this. This will work, but only as long as the name of the
variable does not contain any Tcl metacharacters. Tcl has much in
common with Lisp in that regard in that variable names can be almost
anything:
$ rlwrap tclsh
% set x 20
20
% set {$x} 30
30
% set {x Y} 50
50
% set x
20
% set {$x}
30
% set {x Y}
50
%
For your 'showvar' you want to do this instead:
proc showVar {name} {
upvar 1 $name local
puts "sV:$name=[format %s $local]"
}
Assuming you always want to 'format' as a string. If you just want to
output the variable, you can do:
puts "sV:$name=$local"
The reason why your uplevel version will fail is you are building a tcl
command using string operations (string cat). That works, 99% of the
time, until the 1% when a Tcl metacharacter causes the eval of the
string to fail. The canonical method of building up Tcl commands for
evaluation is to use [list] (which will assure that any metacharacters
are properly quoted to prevent them from being interpreted as
metacharacters.
Scanning through the code, you have more instances where you are using
string operations to build items for evaluation. Many of them will be
just as fragile as showVar when variable names contain unusual
characters.
For instance, your defvar would be better written this way, and would
avoid the same possibilities for odd errors based upon data content:
proc defvar {name delicate_value} {
if {![uplevel 1 [list info exists $name]]} {
uplevel 1 [list set $name $delicate_value]
} else {
return -code error "variable '$name' already exists"
}
}
> If there is more professional-quality implementation of source
> tracking, I'd like to drop my implementation and use that better one.
I've heard that the Geany editor (
http://www.geany.org/) includes a
"jump to Tcl proc defn" function. I do not know how it performs the
jump (most likely by 'grep' type operations).