2014-11-27 1 views
1

В сценарии Tcl я хочу уловить возврат процесса Tcl для выполнения некоторых действий по завершению. Например мой код может выглядеть следующим образом:Tcl Script: Неверное имя команды возвращает при выполнении тела proc

proc X10 { a } { return [expr $a * 10] } 
proc procF {} { 
    set a 13 
    catch {[info body X10]} __result 
    return $__result 
} 
procF 

предыдущий код дает мне ошибку: invalid command name " return [expr $a * 10] "

Хотя что замена info body X10 с return [expr $a * 10] работ, как ожидалось. Первоначально я думал, что они оба взаимозаменяемы и должны давать одинаковый результат. Итак, почему первый дает ошибку и в чем разница между ними?

+0

Если вы хотите, чтобы ваш код работал быстрее и у него было меньше возможных ошибок, определите 'X10' с фигурными скобками вокруг выражения:' proc X1 {a} {return [expr {$ a * 10}]} 'Он позволяет Tcl для байт-кода-скомпилировать его и не будет взорваться на 'X1 {[puts haha; exit]}' ... –

+0

Это хороший момент, я всегда спрашивал себя, почему гиды и ссылки говорят, что лучше заключить выражение с фигурными скобками и я подумал, что это просто какая-то читаемость. Но я не получил эту часть «bytecode-compile», я был бы признателен, если бы вы могли подробнее рассказать об этом или сослаться на меня как на ссылку или ссылку на нее. – Devos

+0

Обратите внимание, что что бы вы ни делали, 'procF' вернет строку« __result ». Вероятно, вы хотите, чтобы вызов был 'return $ __ result' или, что то же самое,' set __result'. –

ответ

1

Ваш код не работает, потому что вы получаете тело X10 и рассматриваете это как имя команды. Tcl не разбивает вещи автоматически для вас - у вас есть ask для этого - и это критический фактор безопасности языка. Вы должны были бы сделать что-то вроде этого:

proc procF {} { 
    set a 13 
    catch {eval [info body X10]} __result 
    return __result 
} 

или это (потому что первый аргумент catch это скрипт):

proc procF {} { 
    set a 13 
    catch [info body X10] __result 
    return __result 
} 

Но я на самом деле быть наклонена в вашем случае (как представлены точно, и пытается интерпретировать то, что вы сказали), чтобы сделать:

proc procF {} { 
    set a 13 
    catch {X10 $a} __result 
    return __result 
} 

Заметим также, что если вы сделали это:

proc procF {} { 
    set a 13 
    catch {info body X10} __result 
    return __result 
} 

то результатом будет определение X10 без его оценки.

+1

Спасибо за ваш ответ. 1. Почему закрытие тела с помощью скобок не означает его команды; Я использовал его без команды 'catch', и это сработало. 2. Как 'catch' интерпретировать несколько операторов в' catch [info body X10] 'без брекетов? 3. Я не могу использовать catch {X10 $ a}, поскольку это добавит дополнительный уровень вызовов, которые мне не нужны, хотя это может быть встречено повышением – Devos

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