1
votes

In a Tcl script, I want to catch the return of a Tcl proc in order to execute some finalization actions. For example my code could be as follows:

proc X10 { a } { return [expr $a * 10] }
proc procF {} {
    set a 13
    catch {[info body X10]} __result
    return $__result
}
procF

The previous code gives me an error: invalid command name " return [expr $a * 10] "

Although that replacing info body X10 with return [expr $a * 10] works as expected. What I initially thought is that both of them are exchangeable and should give the same output. So, why the first gives an error and what is the difference between both of them ?

1
If you want your code to go faster and have fewer possible pitfalls in it, define X10 with braces around the expression: proc X1 {a} {return [expr {$a * 10}]} It enables Tcl to bytecode-compile it and won't blow up horribly on X1 {[puts haha;exit]}Donal Fellows
That 's a good point, I always asked myself why guides and references telling it's better to enclose the expression with braces and I thought it's just some sort of readability. But I did not get that part of "bytecode-compile", I 'd be grateful if you could elaborate more on it or refer to me some sort of a ref or link to it.Devos
Note that whatever you do, procF will return the string "__result". You probably want the invocation to be return $__result or, equivalently, set __result.Peter Lewerin
@Hoodiecrow Yes, you are right. this was a typo mistake, I fixed it. Thank youDevos

1 Answers

1
votes

Your code is failing because you are getting the body of X10 and treating that as a command name. Tcl doesn't split things up automatically for you — you have to ask for it — and this is a critical language safety factor. You'd have to do something like this:

proc procF {} {
    set a 13
    catch {eval [info body X10]} __result
    return __result
}

or this (because the first argument to catch is a script):

proc procF {} {
    set a 13
    catch [info body X10] __result
    return __result
}

But I'd actually be inclined in your case (as presented exactly, and trying to interpret what you've said) to do:

proc procF {} {
    set a 13
    catch {X10 $a} __result
    return __result
}

Note also that if you did this:

proc procF {} {
    set a 13
    catch {info body X10} __result
    return __result
}

then the result would be the definition of X10 without it being evaluated.