Tcl:将参数传递给 class 时计算变量值

Tcl: Evaluate the variable value when passing argument to class

我有一段这样的代码

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

有人可以帮忙解决吗?

改变

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

foo title [list $a $b]

以便变量被它们的值替换。

您想在 {大括号引用的} 字符串中(逻辑上)在脚本中写入的点之后展开替换。通常不推荐这样做(当您可以使用 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 的使用是为了保证我们在外部上下文中为 运行 制作了一个无替换脚本,very 强烈推荐做法.


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

Could someone help to fix it?

我不明白你为什么要先将变量引用打包成一个值,然后再对它们进行上层替换。此外,format 的值参数的数量似乎是固定的。为什么不在 title 方法中使用两个单独的形式参数并直接使用它们?

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

那么就这样调用吧:

foo title $a $b

更新

to generate the title in different length

那么最好像这样使用 args

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

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