Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the magic behind the TCL command expr with the operator eq

Tags:

tcl

I would like to understand the TCL command expr for string comparison:

I tried the following:

expr {t eq t}
=> 1
expr {tru eq tr}
=> 0
expr {tru eq truee}
=> invalid bareword "truee" ...
expr {a eq a}
=> invalid bareword "a" ...

What is the magic behind the words t, tr, tru? Does Tcl special handling for these strings? I learnt that I had to quote the string if I use expr with eq, but I have some legacy programs which use this form of comparison. I would like to understand it. Thanks.

like image 299
kenny-liu Avatar asked Mar 12 '23 08:03

kenny-liu


1 Answers

In Tcl, eq and ne does the string comparison while == does the numerical comparison.

% expr {1 == 1.0}
1
% expr {1 eq 1.0}
0
%

Whenever you are using the eq and if the input non-numeric, then it should be used with double quotes or with a variable reference. You can't use the literal bareword string notation.

For e.g

% expr {"a" eq "b"}; # Strings with double quotes
0
% set i a
a
% expr {$i eq "a"}; # String with variable reference
1
% expr {a eq b}; # Literally using the string as bareword
invalid bareword "a"
in expression "a eq b";
should be "$a" or "{a}" or "a(...)" or ...
%

There is a exception in this rule, where the Tcl boolean comes into play.

In Tcl, a proper boolean value is either a proper integer, with, like in C, zero meaning false and non-zero meaning true, or one of the following:

yes, true, on   --> Boolean 1
no, false, off  --> Boolean 0

When they are used partially, Tcl tends to match with any of the known items and evaluation happens accordingly.

If you evaluate expr with these special words, then it will return the same.

% expr {true}
true
% expr {false}
false
% expr {t}; # Tcl automatically matches internally and map it to 'true'
t
% expr {fa} ; # Similary, mapped to 'false'
fa
% expr {o} ; # Will throw error as it is conflicting with 'on' & 'off'
invalid bareword "o"
in expression "o";
should be "$o" or "{o}" or "o(...)" or ...
% expr {on}
on
% expr {of}; # Matching 'off' boolean 
of

% if true {puts ya}
ya
% if n {puts ya}; # Matching boolean 'no'
% if f {puts ya}; # Matching boolean 'false'
% if false {puts ya}
% if yes {puts ya}
ya
% if y {puts ya}; # Matching boolean 'y'
ya

So, If your input is mapping with boolean, they are still valid, but treated as string only.

Now, lets go back to your original question.

% expr {t eq t}; # Tcl mapped the 'true' boolean and string-wise both are same. So, returned 1
1
% expr {tru eq tr}; # Both mapped 'true'. But, string-wise differs. So, returned 0
% expr {tru eq truee}; # 'tru' mapped to 'true' and 'truee' is unknown. So error
invalid bareword "truee"
% expr {a eq a}; # Both are used literally, so error throw.
invalid bareword "a"

Now, your question from the comments,

% expr {yes == true}; # String-wise, both are different. So, returned 0
0
like image 69
Dinesh Avatar answered Mar 16 '23 00:03

Dinesh