如何在tcl中的调用函数的上下文中执行字符串中的扩展

时间:2013-02-09 20:16:56

标签: tcl

如何在下面的脚本中实现expand(在tcl中正常扩展命令和变量),我希望它打印出来:

'
    hello {
        $b
    }
    {tcl world}
'

这就是我想象的剧本:

proc clever_func {script} {
    set script [uplevel 1 expand [list $script]]
    puts "'$script'"
}

proc isolated_client_function {} {
    set a hello
    set b difficult
    set c tcl
    set d world

    clever_func {
        $a {
            $b
        }
        [list $c $d]
    }
}

isolated_client_function

2 个答案:

答案 0 :(得分:2)

一个例子不足以替代规范,但似乎没有内置的TCL工具做你想要的。可以在单个命令尾上执行替换(通过将list添加到命令中并eval将它放在您想要的任何级别上,但不能用于带有两个“命令”的伪脚本。 (也可以使用subst进行字符串插值,但你可能已经知道为什么它不是你想要的:它也会扩展$b)。

我看到了两种获得你想要的东西的可能性:

  1. 使用sugar::scriptToList对您的输入进行标记,然后在标记列表中手动执行替换,然后使用sugar::listToScript将结果转换回文本格式。 sugar宏处理程序的这些功能旨在让您在保留格式,注释和布局的同时在语义上修改脚本。

  2. 将您的输入细分为单独的“命令”:首先在每个换行符和分号处拆分,然后使用info complete收集与完整“命令”相对应的部分(IIRC会出现一些反斜杠的案例) -newline延续:小心)。在每个完整的“命令”上使用前置"list "的技巧,在必要的上下文中评估结果(uplevel)。因此,对于每个命令,您将获得列表,其中在适当时已执行替换。你将失去每个“命令”内部格式的细微差别(如分隔单词的空格数和空间类型),除非你自己记住它们,否则你将丢失原始的命令分隔符。如果目标是在以后的其他环境中获得一种“预扩展脚本”eval,那么对您来说可能并不坏。

答案 1 :(得分:1)

subst命令将带您到那里。

proc expand {script} {
    uplevel 1 [list subst $script]
}

set a hello
set b difficult
set c tcl
set d world

expand {
    $a {
        $b
    }
    [list $c $d]
}

输出

    hello {
        difficult
    }
    tcl world

我不确定如何防止$b被替换。您可能需要自己解析脚本。

如果您希望最后一部分有您演示的引用,则需要另一级别的列表

expand {
    $a {
        $b
    }
    [list [list $c $d]]
}

输出

    hello {
        difficult
    }
    {tcl world}