2015-01-21 3 views
0

Какой из них является правильным способом использования variable с или без знака доллара? Я думал, что variable (без $) используется только во время variable декларации (по аналогии с Bash):

set var 10 

Во всех остальных случаях, когда variable упоминается или используется (но не декларируется) надлежащий синтаксис $variable$):

set newVar $var 
puts $var 
puts $newVar 

Но потом я нашел код, где он взаимозамене и кажется, что этот код работает:

# 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" 
} 

Выход:

argv IS NOT AN ARRAY 
$argv IS NOT AN ARRAY 
argv IS LIST 
$argv IS LIST 

Редактировать в ответ на @glenn Джекман: ​​

Ваш ответ указал мне на дальнейшие исследования и я нашел, что TCL способен делать какую-то «кода самостоятельно модифицирующего "или что-то еще правильное имя, например:

% 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 
% 

Теперь ваш ответ приносит некоторый свет в проблему, но остается один вопрос. Это выдержка из документации:

set varName ?value? 
array exists arrayName 

Документация говорит, что обе функции ожидают имя переменной (не значение), другими словами, что ожидать variable вместо $variable. Поэтому я предполагаю (на основе выше самомодифицирующего кода), что при переходе $variable вместо variable произошла замена переменных (точно такая же, как и код выше). Но что, если $variable содержит то, что не является списком ни одного массива (мои аргументы во время тестирования были: param0 param1 "param 2" param3). С этой точки зрения вывод, который говорит $argv IS LIST, неверен. Что мне здесь не хватает?

Редактировать в ответ на @schlenk:

Наконец я (надеюсь) понять проблематику. Я нашел great article о TCL, которые объясняют (а не только) эту проблему. Позвольте мне определить несколько мудрое высказывание из этой статьи:

  • В Tcl, что строка представляет до команды, что это манипулировать им.
  • Вся команда в Tcl - как вы видите, нет оператора .
  • if - это команда с двумя аргументами.
  • Имя команды не является особым типом, а просто строкой.

Также following SO answer подтверждает это утверждение:

«В Tcl, значения не имеют типа ... они ставят под сомнение, смогут ли они быть использованы в качестве данного типа." Команда string is integer $a означает:

  • „Могу ли я использовать значение в $a как целое“

НЕ

  • „это значение в $a целое число“

  • «Каждое целое число также действительный список (из одного элемента) ... так что он может быть использован в качестве либо и как строка команды возвращает истину (как будет несколько других для целого) «.

Я считаю, то же самое относится и к string is list команды:

% set abc "asdasd" 
asdasd 
% string is list $abc 
1 
% string is alnum $abc 
1 

string is list возвращает 1, потому что $abc является строка, а также это один элемент списка и т.д. В большинстве учебников есть говорят, что следующий фрагмент является надлежащим способом декларирования и работы со списками:

% set list1 { 1 2 3 } 
% lindex $list1 end-1 
2 

Но когда все в TCL является строкой, в моем опыте также работает следующее (если я ошибаюсь, верьте мне, пожалуйста).

% set list2 "1 2 3" 
1 2 3 
% lindex $list2 end-1 
2 
+0

правила замещения чтения Tcl (в человеке Tcl). Сначала вы получаете группировку аргументов, за которыми следует замена переменных и команд, прежде чем вы получите текущую команду. – schlenk

+0

@schlenk Я сделал, несколько раз, но я до сих пор не хватает точки. Извините –

ответ

1

Важно знать, что $x в Tcl - это просто синтаксический сахар для команды set x. Таким образом, вы можете перевести любой $x в код Tcl на [set x] там же, чтобы посмотреть, что на самом деле происходит.

Другая важная вещь, которую следует учитывать, - неизменные ценности. Значения Tcl неизменяемы, поэтому вы не можете их изменить. Вы можете просто создать новое измененное значение. Но вы можете изменить значение, хранящееся внутри переменной.

Здесь разница между командами, принимающими имя переменной, и значениями, принимающими значение. Если команда хочет изменить значение, хранящееся в переменной, оно принимает имя переменной. Примерами являются lappend, lset, append и так далее. Другие команды возвращают новое значение и принимают значение в качестве аргумента, примеры включают lsort, lsearch, lindex.

Другим важным моментом является то, что у вас действительно нет типа списка. У вас есть строки, похожие на списки. Таким образом, тесты Tcl string is list. Это имеет некоторые последствия, например. вы не всегда можете решить, есть ли у вас строковый литерал или один список элементов, поскольку он часто один и тот же. Пример Дано:

% set maybe_list a 
% string is list $maybe_list 
1 

Объединение, что с ЛСТ почти неограниченные имена переменных, как уже demonstracted Гленн, и вы можете получить действительно запутался. Например, это все допустимые имена переменных Tcl, вы просто не можете использовать их все с $ ярлыка:

% set "" 1  ;# variable name is the empty string 
1 
% puts [set ""] 
% set " " 1  ;# variable name is just whitespace 
1 
% puts [set " "] 
1 
% set {this is a list as variable name} 1 ;# a variable with a list name 
1 
% puts [set {this is a list as variable name}] 
1 
% set Δx 1 
1 
% incr Δx 
2 
% puts [set Δx] 
2 
+0

Спасибо, что он указывает мне на дальнейшее изучение –

2

Это зависит от команды. Некоторым командам Tcl требуется переменная имя в качестве параметра, если необходимо, чтобы изменил содержимое переменной. Некоторые из них являются:

  • набор
  • Foreach
  • lappend
  • прирастить

Большинство, но, конечно, не все команды хотят взять значение переменной.

Вам нужно проверить documentation для соответствующих команд, чтобы увидеть, если параметры включают в себя «имяПерем» (или «dictionaryVariable„), или если параметры названы“строки», " список»и т.д.


пример использования info exists который принимает VarName аргумент:

% set argv {foo bar baz} 
foo bar baz 
% info exists argv    ;# yes the variable "argv" exists 
1 
% info exists $argv    ;# no variable named "foo bar baz" 
0 
% set {foo bar baz} "a value" ;# create a variable named "foo bar baz" 
a value 
% info exists $argv    ;# so now that variable exists 
1 
+0

Благодарим за помощь. Могу ли я спросить, можно ли вызвать указанную документацию непосредственно из 'tclsh'? –

+0

Я не понимаю ваш вопрос. –

+0

Я спрашиваю, есть ли какая-то справочная страница или что-то похожее на python 'help' или perl' perldoc' для [документации] (http://www.tcl.tk/man/tcl8.6/TclCmd/contents.htm) что вы упомянули? Единственное, что я знаю, это 'man Tcl'. Основная цель - использовать его из командной строки без подключения к Интернету. Спасибо –