2013-04-15 2 views
2

Вот код, я тестирование:С помощью команды TCL Eval с «установить»

proc check_eval {} { 
    set cmd {set return_val {}; set return_val} 
    puts "Command to evaluate : $cmd" 
    uplevel eval $cmd 
} 

я столкнулся со следующей проблемой: когда я называю «check_eval», это выглядит как заявление «набор Return_Val {} msgstr "игнорируется. I.e., интерпретатор ищет существующую переменную return_val в области вызова. Пример:

tcl>unset return_val 
tcl>check_eval 
Command to evaluate : set return_val {}; set return_val 
can't read "return_val": no such variable 
while evaluating check_eval 


tcl>set return_val 556 
556 
tcl>check_eval 
Command to evaluate : set return_val {}; set return_val 
556 
tcl> 

С другой стороны, если заменить "установить Return_Val {}" в процедуре, например, "установить Return_Val 10000", он будет показывать 10000 при работе:

tcl>set return_val 556 
556 
tcl>check_eval 
Command to evaluate : set return_val 10000; set return_val 
10000 
tcl>set return_val 
10000 

Кто-нибудь может объяснить мне, пожалуйста, что здесь происходит?

Спасибо.

ответ

4

Вы делаете два уровня оценки/интерпретации, сначала с uplevel, затем с eval, а группировка фигурных скобок вокруг скрипта cmd защищает вас только от первого.

Вам не нужно eval, этого будет достаточно:

uplevel $cmd 

EDIT: Оба eval и uplevelconcat: Enate все свои аргументы вместе в плоскую строку и оценить его как сценарийuplevel вы можете выбрать другой стек стека, чтобы запустить его). Они не используют первый аргумент в качестве одиночной команды, а остальные аргументы в качестве аргументов для отправки этой команде. Если это так, вы получите сообщение об ошибке с вашего eval, что команда «set return_val {}; set return_val» не найдена. Таким образом, вы правильно используете eval, но uplevel неправильно.

uplevel работает этот скрипт ...

eval set return_val {}; set return_val 

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

eval не нужен в вашем примере, но если вам нужно вызвать единственную команду uplevel, без его аргументы получать сцепляются, как процитировать статические строки, когда вам не нужны какие-либо замены, это фигурные скобки:

uplevel {after 1000 {set return_val {}; set return_val}} 

... и способ цитировать динамические строки с замещенными значениями в нем, является с list:

set cmd {set return_val {}; set return_val} 
uplevel [list after 1000 $cmd] 
+0

@mkostya, читать [ "Eval и Цитируя"] (HTTP: // beedub .com/book/3rd/Eval.pdf) из книги, чтобы лучше понять e цитирование вопросов. – kostix

+1

Альтернативно, 'uplevel [list eval $ cmd]'. Это абсолютно то же самое, что и 'uplevel $ cmd', поэтому угадайте, что лучше ... –

+0

Спасибо всем (особенно potrzebie) за ответы! – mkostya

Смежные вопросы