Tcl:将参数传递给类时评估变量值

时间:2020-03-04 13:39:54

标签: tcl

我有一段这样的代码

oo::class create class_test {
    variable title_text
    variable result
    method title {t} {
        set title_text $t
        set result [format "%-6s %-6s" {*}$title_text]
    }
    method print {} {
        return $result
    }
}

set a "abcde"
set b "fghij"
class_test create foo
foo title {"$a" "$b"}
puts [foo print]

实际输出是

$a     $b

预期输出是

abcde  efghi

有人可以修复它吗?

3 个答案:

答案 0 :(得分:2)

更改

foo title {"$a" "$b"}

foo title [list $a $b]

以便变量被其值替换。

答案 1 :(得分:1)

您想在逻辑上将{用括号括起来的}字符串内的替换内容扩展(在逻辑上)。通常不建议这样做(不是当您可以正确地使用list构造参数时),但是您可以做到这一点。

method title {t} {
    set title_text [lmap value $t {
        uplevel 1 [list subst $value]
    }]
    set result [format "%-6s %-6s" {*}$title_text]
}

我们对自变量(lmap)中的每个单词进行转换,转换将对其应用subst,这必须在调用者的上下文(uplevel 1)中进行。在其中使用list是为了保证我们制作一个无替换脚本以在外部上下文中运行,这是 非常强烈推荐的做法


TclOO的一个功能是,与其他一些较旧的Tcl对象系统不同,使用TclOO时不需要采取特别的预防措施来使用uplevel(或upvar)。这使得在方法中执行此类操作比在常规过程中执行此操作更为棘手。即使存在继承也是如此。

答案 2 :(得分:0)

有人可以修复它吗?

我不明白为什么您首先将变量引用打包到单个值中,然后再将其替换。此外,format的值参数的数量似乎是固定的。为什么不对您的title方法使用两个单独的形式参数并直接使用它们呢?

method title {v1 v2} {
    set result [format "%-6s %-6s" $v1 $v2]
}

然后这样称呼它:

foo title $a $b

更新

生成不同长度的标题

那么最好像这样使用args

method title {args} {
    set result [format [join [lrepeat [llength $args] "%-6s"] " "] {*}$args]
}

args是在Tcl中使用带有可变参数的方法(proc)的自然方法。