Which one is proper way of using variable
with or without dollar sign? I thought that variable
(without $
) is used only during variable
declaration (similar to Bash):
set var 10
In all other cases when variable
is referred or used (but not declared) the proper syntax is $variable
(with $
):
set newVar $var
puts $var
puts $newVar
But then I found code where it is interchanged and seems that this code is working:
# using argv
if {[array exists argv]} {
puts "argv IS ARRAY"
} else {
puts "argv IS NOT AN ARRAY"
}
# using $argv
if {[array exists $argv]} {
puts "\$argv IS ARRAY"
} else {
puts "\$argv IS NOT AN ARRAY"
}
# using argv
if {[string is list argv]} {
puts "argv IS LIST"
} else {
puts "argv IS NOT LIST"
}
# using $argv
if {[string is list $argv]} {
puts "\$argv IS LIST"
} else {
puts "\$argv IS NOT LIST"
}
Output:
argv IS NOT AN ARRAY
$argv IS NOT AN ARRAY
argv IS LIST
$argv IS LIST
Edit in reply to @glenn jackman:
Your reply pointed me to further research and I've found that TCL is capable doing some sort of "self modifying code" or whatever is correct name e.g.:
% set variableName "x"
x
% puts $x
can't read "x": no such variable
% set $variableName "abc"
abc
% puts $x
abc
% puts [set $variableName]
abc
%
%
%
%
%
%
% set x "def"
def
% puts $x
def
% puts [set $variableName]
def
%
Now your answer bring some light to problem, but one question remains. This is excerpt from documentation:
set varName ?value?
array exists arrayName
Documentation says that both functions expect variable name (not value) in other words it expect variable
instead of $variable
. So I assume (based on above self modifying code) that when I pass $variable
instead of variable
the variable substitution took place (exactly the same as code above). But what if $variable
contains something that is not a list neither array (my arguments during testing was: param0 param1 "param 2" param3). From this point of view the output that says $argv IS LIST
is wrong. What am I missing here?
Edit in reply to @schlenk:
Finally I (hope) understand the problematic. I've found great article about TCL, which explain (not just) this problematic. Let me pinpoint a few wise statement from this article:
- In Tcl what a string represents is up to the command that's manipulating it.
- Everything is a command in Tcl - as you can see there is no assignment operator.
if
is a command, with two arguments.- The command name is not a special type but just a string.
Also following SO answer confirms this statement:
"In Tcl, values don't have a type... they question is whether they can be used as a given type."
The command string is integer $a
means:
- "Can I use the value in
$a
as an integer"
NOT
"Is the value in
$a
an integer""Every integer is also a valid list (of one element)... so it can be used as either and both string is commands will return true (as will several others for an integer)."
I believe the same applies also for string is list
command:
% set abc "asdasd"
asdasd
% string is list $abc
1
% string is alnum $abc
1
string is list
returns 1 because $abc
is string and also it is one element list etc. In most tutorials there are said that following snippet is the proper way of declaring and working with lists:
% set list1 { 1 2 3 }
% lindex $list1 end-1
2
But when everything in TCL is string the following is also working in my experience (if I am wrong correct me please).
% set list2 "1 2 3"
1 2 3
% lindex $list2 end-1
2