将包含变量的字符串传递给tcl中的proc,而不进行评估

时间:2018-03-29 01:16:04

标签: tcl

我想将一个字符串传递给包含变量的proc,而不是评估/替换变量的值,例如:

% set intf "blah"  
% set cmd "show router interface $intf"
% dummy_proc $cmd

要求是,$cmd收到的dummy_proc应该是" show router interface $intf"而不是" show router interface blah"

我正在寻找不涉及以下内容的答案:

  1. 使用$ =>的反斜杠\$
  2. 将字符串包裹在花括号{}
  3. 我很感激任何帮助。感谢

3 个答案:

答案 0 :(得分:0)

简单。例如,您可以使用以下方法之一:

set cmd "show router interface \x24intf"
set cmd [format "show router interface $%s" intf]
append cmd "show router interface " $ intf
set cmd [string cat "show router interface " $ intf]

但我希望这不是你想要的。

Tcl提供了一种非常简单且富有表现力的方式来指定最小替换字符串:

set cmd {show router interface $intf}

这具有清晰的优点,并且不会使解释器复杂化,除了Tcl使用的简单评估规则之外。

文档: Summary of Tcl language syntax

答案 1 :(得分:0)

使用大括号有很多难看的替代方法,例如:

    set cmd [string map "% $" "show router interface %intf"]
    set cmd [join [list "show router interface $" "intf"] ""]
    set cmd [format "show router interface %sintf" $]
    set cmd "show router interface [set $ $]intf"
    set cmd $; set cmd "show router interface [set cmd]intf"
    set cmd "show router interface [lindex $ 0]intf"

为什么你想要使用这些替代品而不是支撑是一个谜。

答案 2 :(得分:0)

问题是Tcl在程序获取之前统一替换这些位;它是如何定义语言来运作的。您可以获得的唯一额外信息是(如果您的Tcl版本足够新):

proc example {cmd} {
    puts call=[dict get [info frame -1] cmd]
    puts cmd=$cmd
}
set intf "blah"  
set cmd "show router interface $intf"
example $cmd

将打印:

call=example $cmd
op=show router interface blah

cmd的设置已经结束,并且在您要检查时已完成。

使用轻微更自由的要求解决此问题的方法是:

proc example {cmd} {
    puts "supplied: $cmd"
    # Do the substitutions as in "double quotes" *in the caller's context*
    set cmd [uplevel 1 [list subst $cmd]]
    puts "substituted: $cmd"
}
set intf "blah"  
set cmd {show router interface $intf}
example $cmd

打印:

supplied: show router interface $intf
substituted: show router interface blah

不能解决这个问题而不延迟$intf的替换直到评估程序,并且要求括号或列出的(丑陋)策略在其他答案。 Tcl风格真的鼓励使用大括号来做这类事情,双引号总是意味着内部的变量(和命令调用)要立即替换。延迟替换(你有工具),你可以在你需要的时候替换。