Tcl 如何使用参数列表中的参数调用过程

Tcl 如何使用参数列表中的参数调用过程,tcl,Tcl,这是TCL8.4 我正在尝试创建一个过程,该过程可以在用户指定的任何其他过程上执行一些常见的操作 例如: proc process_menu_item {command args {count 1}} { set inf [expr {$count == -1 ? 1 : 0}] set end_str [expr {$count == -1 ? "inf" : $count}] set loop_cnt 0 while {$inf || $count

这是TCL8.4

我正在尝试创建一个过程,该过程可以在用户指定的任何其他过程上执行一些常见的操作

例如:

proc process_menu_item {command args {count 1}} {
    set inf     [expr {$count == -1 ? 1 : 0}]
    set end_str [expr {$count == -1 ? "inf" : $count}]
    set loop_cnt 0

    while {$inf || $count > 0} {
        incr loop_cnt
        puts [format "------- %s -------" [bold "LOOP $loop_cnt of $end_str"]]

        $command $args
    }
    return
}
我希望这个过程只执行指定的$command$count次。 我遇到的问题是传递参数

假设我想调用这样的过程:

proc example {{par_a {-1}} {par_b {-1}} {par_c 1}} {
    puts "All params: $par_a $par_b $par_c"
}
process_menu_item frobnicate [list foo bar]
我应该如何调用
process\u菜单项
?有可能吗?我尝试了一个字符串,一个列表,但最终
par_a
得到了一个包含所有参数的大列表


谢谢。

您始终可以构造包装函数:

proc wrapper {arg_list} {
    example [lindex $arg_list 0] [lindex $arg_list 1] [lindex $arg_list 2]
}
TCL 8.5有专门针对这类事情设计的:

% proc test {a b c} {
    puts a
    puts b
    puts c
}
%
% set inp [list "A" "B" "C"]
A B C
% test $inp
wrong # args: should be "test a b c"
% test {*}$inp
a
b
c
(首先,一个过程的
args
参数只有在它最后一个时才有魔力。在它后面加上任何东西,它就会变成一个普通变量。正如您所知。当然,这可能就是您在这里需要的!)

要调出
过程菜单项
,您需要更改:

$command $args
为此(Tcl 8.4或更早版本):

好吧,如果你是偏执狂,你会写下:

eval [list $command] [lrange $args 0 end]
或者您使用Tcl 8.5(或更高版本):

然后,您可能会构建对
process\u菜单项的调用,如下所示:

proc example {{par_a {-1}} {par_b {-1}} {par_c 1}} {
    puts "All params: $par_a $par_b $par_c"
}
process_menu_item frobnicate [list foo bar]
除了使用
list
(许多Tcl命令可以生成列表)之外,还有其他几种方法,或者您可以使用文字:

process_menu_item frobnicate {foo bar}

不建议在该文本中添加任何引用
process\u menu\u item
中的变量的内容(仅适用于最短的
eval
形式)。它可以让你做一些很棒的事情,但它也非常脆弱。如果您想传入循环变量,这是很有可能的,但它需要更高级的技术(您应该问另一个问题)。

我现在无法给出更全面的答案,但是
interp alias
可能会帮助您达到目的。有一个例子。如果这不合适,也许可以探索一下——每个命令都会触发这些命令,您可以根据命令名进行选择。

所以必须为每个可以调用的过程编写包装器?