Почему Tcl не использует знак доллара перед именами переменных при вызове «set»? - PullRequest
6 голосов
/ 04 сентября 2011

Я просто собираюсь использовать Perl для сравнения:

$foo = 5;
print $foo;

устанавливает переменную $foo равной 5, а затем печатает содержимое переменной (обратите внимание, что к $foo всегда обращаютсяas $foo).

В Tcl:

set foo 5
puts $foo

делает то же самое, что и аналог Perl.

Почему Tcl не устанавливает переменные с помощью "$", но вам нужен" $ "для доступа к переменной?Почему это верно и для процедур (например, proc bar {spam eggs} {...})?Для меня код Tcl выглядит следующим образом (в псевдокоде):

"foo" = 5 # Setting a string?
puts $foo # "$foo" is not defined.

(мои комментарии отражают только то, что происходит, а не то, что происходит).

Еще один момент, который я хотел бы добавить, это ясность:

set foo foo

Да, я всегда мог бы сделать set foo "foo", но не set $foo foo более последовательным?

Отчто я знаю, «foo» может быть переменной или строкой, в зависимости от ситуации, как видно из моего последнего примера (set foo foo = set var string), но я не понимаю этот синтаксис (возможно, потому что япривык к питону ...)

Ответы [ 4 ]

13 голосов
/ 04 сентября 2011

Я думаю, что исходный Tcl имел только команду set, поэтому единственный способ получить содержимое переменной "foo" - вызвать set foo.Но поскольку Tcl перешел в область языков сценариев общего назначения (напомним, что Tcl был задуман как встраиваемый язык, в котором вы используете тонкий слой Tcl над скомпилированными компонентами, написанными на C, так что никто не ожидал использовать много переменных) считалось, что синтаксический сахар $ varname полезен, и поэтому он был добавлен.

Другими словами, Tcl не использует «$» так же, как Perl, в котором «$»означает «интерпретировать все, что следует, как скаляр», также как «$» в Tcl не обозначает переменную.Вместо этого это просто синтаксический сахар для «дайте мне значение переменной, имя которой дается непосредственно следующим словом».

12 голосов
/ 05 сентября 2011

Ну, я решил прокомментировать последние биты исходного вопроса, но комментарий перерос предел, и поэтому я опубликую его как ответ, даже если он не отвечает на указанный вопрос. Я надеюсь, что это прояснит некоторые вещи, которые, как представляется, подразумеваются в этом вопросе.

Примечание о согласованности set foo foo: вы подходите к Tcl несколько неправильно. Tcl радикально отличается от Perl или Python тем, что почти не имеет синтаксиса (на самом деле, как LISP). "set foo foo" - это не синтаксис для установки переменной, как это может быть на другом языке, это вызов команды в настоящее время , доступной под именем "set", и передача ей двух аргументов - "foo "и" фу "; То, что зарегистрировано под именем команды set, решает, каково имя переменной и какое значение установить. Аналогично, циклические команды - это не синтаксис, а команды. Действительно, стоит остановиться здесь и подумать, что

for {set i 0} {$i < 10} {incr i} {
  puts $i
}

- это не просто причудливая идея дизайнера языка использовать вместо этого фигурные скобки или «нормальные» скобки, как в C. Вместо этого, здесь анализатор Tcl анализирует пять слов, выбирает первое слово как имя команды, выглядит это, и передает это остальным словам; это реализация for, которая интерпретирует эти {set i 0}, {$i < 0} и т. д. и выполняет их соответствующим образом. Синтаксис существует только для того, чтобы указать, как слова выделяются из входного потока символов. И поскольку все реализовано с помощью команд, ваши команды могут вести себя не так, как встроенные; это позволяет вам создавать собственные мощные команды, такие как for или switch (что-то похожее на макросы в LISP). На другом языке это было бы равносильно способности расширять синтнакс произвольным образом.

Когда эта идея "щелкает", Tcl больше не будет казаться странным. И именно это свойство делает Tcl легко расширяемым (и встраиваемым): поскольку команды, которые вы предоставляете со своей стороны C, ведут себя точно так же, как все встроенные команды.

3 голосов
/ 04 сентября 2011

Думайте о $foo как о значении переменной foo, т. Е. О тексте, который был установлен в последний раз.Теперь, если foo в настоящее время имеет значение x, set $foo y означает set x y, что явно не то, что подразумевается.Это на самом деле более согласованно, чем другие языки, где foo иногда означает значение переменной foo, а иногда и самой переменной foo.

2 голосов
/ 04 сентября 2011

Реальный ответ, если таковой имеется, могли дать только дизайнеры оригинального языка (Джон Оустерхаут), я думаю.Таким образом, все остальное открыто для спекуляций или (образованных) догадок.Есть некоторая история по TCL здесь , но при быстром чтении там нет прямого ответа.

Почему Tcl не устанавливает переменные с помощью "$", ноВам нужен "$" для доступа к переменной?

Мое предположение заключается в том, что таким образом он будет ближе к языкам оболочки (UNIX).TCL был задуман в Беркли, возможно, в сильной среде UNIX (или BSD в этом отношении).

Оболочки UNIX также не используют знак $ (или эквивалент для соответствующей оболочки) при объявлении или назначении переменных, нотребовать его при обращении к нему:

# bourn shell like shells (sh, bash, ksh, ...)
foo=foo
echo "The value of the variable foo is $foo."

Даже нечестивый процессор Windows CMD.EXE использует сопоставимый метод (хотя я предполагаю , что не было тем, что имели в виду дизайнеры TCL; -)

REM DOS COMMAND.COM / Windows CMD.EXE
set foo=foo
echo The value of the variable is %foo%.

Кроме того, «строковые значения» (хотя общеизвестно, что оболочки имеют общеизвестно слабый тип) обычно не требуют кавычек, если в строковом значении теперь есть пробелы.

Да, явсегда можно было бы установить foo "foo", но разве не установить $ foo foo более последовательным?

Ну, это не для дизайнеров / создателей TCL; -)

РЕДАКТИРОВАТЬ Я почти забыл: на самом деле вы могли бы сделать следующее в TCL:

set foo bar
set $foo something
puts $bar

Это фактически выведет "что-то".Вторая строка фактически устанавливает строку «что-то» в значение переменной «foo», таким образом устанавливая переменную с именем «bar» и присваивая ей значение «что-то».

...