Как правило, я бы позволил пользователю указать префикс команды в качестве списка Tcl (для этого тривиально подходят самые простые имена команд), который вы затем применили бы к аргументу, выполнив:
set mangled [{*}$commandPrefix $valueToMangle]
Это позволяет людям предоставлять практически все, что они хотят, тем более что они могут использовать apply
и лямбда-термин для манипулирования вещами по мере необходимости. Конечно, если вы находитесь в процедуре, то вам, вероятно, лучше сделать:
set mangled [uplevel 1 [list {*}$commandPrefix $valueToMangle]]
, чтобы вы работали в контексте вызывающего (измените 1
на #0
, чтобы использовать вместо этого - глобальный контекст), который может помочь защитить вашу процедуру от случайных изменений и упростить использование upvar
в mangler.
Если источник префикса искажения не заслуживает доверия (что это означает, зависит в значительной степени от вашего приложения и развертывания), тогда вы можете запустить искажающий код в отдельном интерпретаторе:
# Make the safe evaluation context; this is *expensive*
set context [interp create -safe]
# You might want to let them define extra procedures too
# interp invokehidden $context source /the/users/file.tcl
# Use the context
try {
set mangled [interp eval $context [list {*}$commandPrefix $valueToMangle]]
} on error {msg} {
# User supplied something bad; error message in $msg
}
Существуют различные способы поддержки пользователей, определяющих преобразование, но если вы можете предоставить им тот факт, что вы работаете с Tcl, тогда это, вероятно, самый простой и самый гибкий.