Reputation: 797
Why doesn't this work like I would think?
set x [if {1} {return 2} {return 3}]
The command output shows 2
, but when you check the value of x
, it is found to be undefined..!
I have read a workaround, ...
proc give {x} {return $x}
set x [if {1} {give 2} {give 3}]
...but I don't understand why the first one doesn't work.
From the tcl 8.5 documentation for if
:
"The return value from the command is the result of the body script that was executed, or an empty string if none of the expressions was non-zero and there was no bodyN."
Questions:
set x [if {1} {return 2} {return 3}]
set a value for x
?set x [if {1} {return 2} {return 3}]
doesn't work, how does tclsh
display "2
" on the interactive shell?tclsh
displays "2
" on the interactive shell, how is it that set x
remains undefined?Upvotes: 4
Views: 1548
Reputation: 5029
The reason that set x [if {1} {return 2} {return 3}]
doesn't work the way you expect, is, as already pointed out, the fact that return
is a command that causes script evaluation to terminate. The "workaround", using a give
procedure, demonstrates the fact that by default, the return
command terminates 1 level of the call stack.
However, the "workaround" really is a pointless exercise in masochism: The return
command allows you to specify where to return to, using the -level
option introduced in Tcl 8.5. Try this, see how it works for you.
set x [if {1} {return -level 0 2} {return -level 0 3}]
Upvotes: 2
Reputation: 27104
See http://www.tcl.tk/man/tcl8.6/TclCmd/return.htm
Return codes are used in Tcl to control program flow. A Tcl script is a sequence of Tcl commands. So long as each command evaluation returns a return code of TCL_OK, evaluation will continue to the next command in the script. Any exceptional return code (non-TCL_OK) returned by a command evaluation causes the flow on to the next command to be interrupted. Script evaluation ceases, and the exceptional return code from the command becomes the return code of the full script evaluation. This is the mechanism by which errors during script evaluation cause an interruption and unwinding of the call stack. It is also the mechanism by which commands like break, continue, and return cause script evaluation to terminate without evaluating all commands in sequence.
So the evaluation of the script is aborted, x
does not get set, and 2
is returned and printed as a result.
Upvotes: 7
Reputation: 246807
The expr
command returns a value, so
set x [if 1 {expr 2} {expr 3}]
But if you're doing that, you might as well use the ternary operator
set x [expr {1 ? 2 : 3}]
Upvotes: 7