TCL conditional commands using ternary operator
Asked Answered
D

1

5

is it possible to run conditional commands using TCL's ternary operator?

using if statement

   if {[string index $cVals $index]} {
       incr As
    } {
       incr Bs
    }

I would like to use ternary operator as follows but I get an error

invalid command name "1" while executing "[string index $cVals $index] ? incr As : incr Bs"

[string index $cVals $index] ? incr As : incr Bs
Dev answered 13/3, 2016 at 2:18 Comment(0)
J
11

For ternary conditions, we should be using boolean values only, either 0 or 1.

So, you can't use string index directly, since it will return either a char or empty string. You have to compare whether the string is empty or not.

Also, the for the pass/fail criteria of conditions, we have to give literal values. You should use expr to evaluate the expressions.

A basic example can be ,

% expr { 0 < 1 ? "PASS" : "FAIL" }
PASS
% expr { 0 > 1 ? "PASS" : "FAIL" }
FAIL
%

Note that I have used double quotes for the string since it has the alphabets. In case of numerals, it does not have to be double quotes. Tcl will interpret numbers appropriately.

% expr { 0 > 1 ? 100 : -200 }
-200
% expr { 0 < 1 ? 100 : -200 }
100
%

Now, what can be done to your problem ?

If you want to use any commands (such as incr in your case), it should be used within square brackets, to mark that as a command.

% set cVals "Stackoverflow"
Stackoverflow
% set index 5
5
% # Index char found. So, the string is not empty.
% # Thus, the variable 'As' is created and updated with value 1
% # That is why we are getting '1' as a result. 
% # Try running multiple times, you will get the updated values of 'As'
% expr {[string index $cVals $index] ne {} ? [incr As] : [incr Bs] }
1
% info exists As
1
% set As
1
% # Note that 'Bs' is not created yet...
% info exists Bs
0
%
% # Changing the index now... 
% set index 100
100
% # Since the index is not available, we will get empty string. 
% # So, our condition fails, thus, it will be increment 'Bs'
% expr {[string index $cVals $index] ne {} ? [incr As] : [incr Bs] }
1
% info exists Bs
1
%
Joanejoanie answered 13/3, 2016 at 2:40 Comment(4)
Thanks works great!, I wonder is the performance is still the same whether we use the ternary operator or if statement? The if statement uses expr behind the scenes so I am guessing it would be around the same.Dev
Yes. It should be. (May be Mr.Donal Fellows/Glenn Jackman will comment if I am wrong in terms of internal behind-the scene stuffs.)Joanejoanie
Performance shouldn't be an issue either way. I'd use if because it's more readable and maintainable (less "clever").Mickel
Performance should be pretty much the same — it's all the same sort of thing in the bytecode — but rather than guessing about it, measure it with time and know for sure.Gender

© 2022 - 2024 — McMap. All rights reserved.