Странная причуда TCL

Так что я очень новичок и неопытен в способах программирования TCL. Я написал скрипт, который вызывает proc, написанный кем-то другим, предварительно удалив выходной файл. Затем он выполняет некоторую дополнительную логику, которую я написал.

Я переместил логику во второй процесс, и сразу куча ее сломалась (а именно команды rm).

Из того, что я могу сказать, первая программа в строке внутри центрального исполнения (текст, следующий за определениями proc) выполняется нормально без команды «exec». Однако, если вы переместите его внутрь процедуры, теперь ему нужна команда «exec».

Может ли кто-нибудь объяснить мне, почему TCL ведет себя таким образом?

e.g.

proc helloworld {} {
  puts "hi"
}
#works
rm my_file 
helloworld

..

proc helloworld {} {
  #doesn't work
  rm my_file 
  puts "hi"
}
helloworld

..

proc helloworld {} {
  #works
  eval rm my_file 
  puts "hi"
}
helloworld

..

proc helloworld {} {
  #works
  file delete my_file 
  puts "hi"
}
helloworld

*Обратите внимание, что это странное поведение может быть связано с программой, которую я передаю скрипту vmd, у которой есть собственное встроенное поведение TCL. Может быть, в своих ответах вы укажете, является ли это нормой и для других переводчиков?


person Jason R. Mick    schedule 14.10.2010    source источник
comment
file delete предпочтительнее exec rm ...   -  person glenn jackman    schedule 14.10.2010
comment
Да, я переключил все свои утверждения на это, чтобы быть более tcl-иш. Я всегда стараюсь использовать встроенную функциональность языка сценариев вместо обычных внешних программ, хотя, как правило, есть много способов снять шкуру с метафорического животного из семейства кошачьих. Это кажется хорошей идеей, так как это сделает код менее зависимым от платформы/дистрибутива.   -  person Jason R. Mick    schedule 14.10.2010


Ответы (1)


Сеанс интерактивного tclsh попытается exec выполнить неизвестную команду (например, rm). Вы не можете рассчитывать на такое поведение при неинтерактивном выполнении скрипта или, как вы обнаружили, в процессах.

Я не вижу, чтобы это было задокументировано в tclsh страница, но неизвестная справочная страница. См. также страницу tclsh на вики Tcl. В интерактивном сеансе tclsh вы можете увидеть, что делает unknown, набрав:

info body unknown

[Обновить]

Цитата из «Практического программирования в Tcl и Tk»:

Команда unknown предоставляет несколько других удобств. Они используются только при непосредственном вводе команд. Они отключаются, как только выполнение входит в процедуру или если оболочка Tcl не используется в интерактивном режиме. Удобными функциями являются автоматическое выполнение программ, история команд и сокращение команд. Эти параметры пробуются по порядку, если реализация команды не может быть загружена из библиотеки скриптов.

person glenn jackman    schedule 14.10.2010
comment
Интересно. Это удивительно, учитывая, что такое поведение кажется плохой идеей. Если бы я писал интерпретатор tclsh/tcl, мне всегда требовался бы оператор exec для согласованности. Иногда такое разрешение кажется верным путем к катастрофе, особенно если учесть, что разнообразие языков сценариев означает, что многие люди, пишущие на языке x, не знакомы со всеми его тонкостями. Есть ли ветераны TCL, которые могут объяснить, почему используется этот подход? - person Jason R. Mick; 14.10.2010
comment
Я предполагаю, что эти функции были добавлены, чтобы сделать интерактивный сеанс Tcl более похожим на оболочку unix. Tcl был написан как связующий язык, очень похожий на оболочку Unix (простое выполнение внешних команд). Возможно, доктор Оустерхаут или один из первых разработчиков Tcl был поклонником csh, учитывая то, как работает история команд (!!, ^old^new и т. д.). - person glenn jackman; 14.10.2010
comment
Я уверен, что это попадает в категорию того, что в то время казалось хорошей идеей. Это делает tclsh более похожим на оболочку для автоматического запуска внешних команд, если нет процедуры с таким именем. Что касается того, почему это работает только на верхнем уровне, как упомянул Гленн, есть несколько других удобных функций, встроенных в unknown, включая историю команд, которую вы, вероятно, никогда не сможете надежно использовать в скрипте. - person Mark Bessey; 14.10.2010
comment
Первоначально Tcl не был написан как связующий язык. Он был написан как командный язык (что означает: оболочка). Отсюда и его название: Tool Command Language (что означает: оболочка для ваших инструментов, здесь инструмент относится к программам САПР или любому другому исполняемому файлу, написанному на C). Поначалу Оустерхаут был весьма удивлен тем, что люди взяли его язык и написали большие программы, подобные той, которая управляла морской буровой платформой. - person slebetman; 18.10.2010