Reputation: 720
I defined 3 (global) constant for string first:
set kColorGBegin "\x1b\[1;32m"
set kColorRBegin "\x1b\[1;31m"
set ColorEnd "\x1b\[0m"
then I create 2 functions rendering and printing input string:
proc r_puts {strs} {
puts "${kColorRBegin} ${strs} ${ColorEnd}"
}
proc g_puts {strs} {
puts "${kColorGBegin} ${strs} ${ColorEnd}"
}
and invoke:
[r_puts "foo"]
[g_puts "bar"]
I got there error message when run this program:
can't read "kColorRBegin": no such variable
while executing
"puts "${kColorRBegin} ${strs} ${ColorEnd}""
(procedure "r_puts" line 2)
invoked from within
"r_puts "foo""
invoked from within
"[r_puts "foo"]"
(file "./t.tcl" line 14)
How do I solve it?
Full code here:
set kColorGBegin "\x1b\[1;32m"
set kColorRBegin "\x1b\[1;31m"
set ColorEnd "\x1b\[0m"
proc g_puts {strs} {
puts "${kColorGBegin} ${strs} ${ColorEnd}"
}
proc r_puts {strs} {
puts "${kColorRBegin} ${strs} ${ColorEnd}"
}
[r_puts "foo"]
[g_puts "bar"]
Upvotes: 1
Views: 462
Reputation: 246942
Don't put braces around the calls to r_puts and g_puts: that will invoke the procs as command substitutions, replace the command substitution with the results, and then try to execute the results as commands.
Demo:
$ tclsh
% proc r_puts {msg} {puts $msg}
% r_puts hello
hello
% [r_puts hello]
hello
ambiguous command name "": after append apply ...
Upvotes: 1
Reputation: 137627
In Tcl, all variables in procedures are local to the procedure unless you say otherwise in that procedure; having to be explicit about this saves all sorts of trouble in the long run. (Things are slightly more complicated in object methods, but you're not dealing with those, and even then they only get complicated when you explicitly ask for it.) This is done most often using the global
command inside the procedure, like this:
proc r_puts {strs} {
global kColorRBegin ColorEnd
puts "${kColorRBegin} ${strs} ${ColorEnd}"
}
proc g_puts {strs} {
global kColorGBegin ColorEnd
puts "${kColorGBegin} ${strs} ${ColorEnd}"
}
You'll probably want to omit the spaces between the variable substitutions.
The other commands used for this are: variable
(usually when working with small numbers of variables in a namespace other than the global one), upvar
(when working with variables passed by name from a caller), and namespace upvar
(when working with many variables in a namespace other than the global one).
Upvotes: 1