TCL subst or eval command is not working in my case ..

前端 未结 3 2069
醉酒成梦
醉酒成梦 2021-01-26 10:30
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         


        
相关标签:
3条回答
  • 2021-01-26 10:48

    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.

    0 讨论(0)
  • 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!"
    
    0 讨论(0)
  • 2021-01-26 10:53

    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}]
    
    0 讨论(0)
提交回复
热议问题