subst or eval command is not working in my case ..
% proc sum {a b} {
return [expr $a+$b]
}
%
% set a 1
1
% set b 2
2
% sum $a $b
3
%
% sum {$a} {$b}
can\'t use n
First, you do understand why “$a
“ isn't a value you can add to? It's not a number at all. (I don't mean $a
, the instruction to read from a variable and substitute it, I mean the string consisting of a $
followed by an a
.)
When you put braces round things in Tcl, it means “don't do anything with this string at all; use it as-is”. Always. (Sometimes you're feeding that string into a command that evaluates, but not always.) When you put square brackets round things, it means evaluate that string as a script immediately and use the result of the script as the value to substitute. Always.
When you do:
subst [sum {$a} {$b}]
You need to understand that the call to sum
is done while assembling the arguments to subst
. That call produces an error, so the call to subst
never happens. Similarly with the eval
form you used.
If we use a somewhat less surprising form:
subst {sum {$a} {$b}}
Then you'll get this out: sum {1} {2}
. subst
doesn't understand the overall string as a script. On the other hand, with:
eval {sum {$a} {$b}}
In this case you get an error not from the eval
as such, but rather from the fact that the call to sum
inside is still erroneous.
I suppose you could do:
eval [subst {sum {$a} {$b}}]
But really don't. There's got to be a simpler and less error-prone way.
You don't understand Tcl correctly.
subst
takes a string and substitues all variables in it, right.
But you pass the result of sum {$a} {$b}
into it, which fails.
So you could either subst
each parameter before you call sum
:
sum [subst {$a} {$b}]
Or modify the sum to do the evaluation for you:
proc sum {a b} {
uplevel 1 [list expr $a + $b]
}
expr
does an own round of evaluation, this is why you usually pass a litteral string (enclosed with {}
) to it, but in this case we actually use this fact. uplevel
executes the command in the context of the caller.
If you call a command, Tcl will replace the variables before the actuall call is made, so maybe this snippet could help you to understand Tcl a little bit better:
set a pu
set b ts
$a$b "Hello World!"
You put the square braces []
to the wrong place (resp. you even don't need them in the eval
case). In the way you wrote the commands the sum {$a} {$b}]
is evaluated before the subst
or eval
command could evaluate the contents of $a
and $b
.
Correct is:
eval sum {$a} {$b}
or
sum [subst {$a}] [subst {$b}]