【问题标题】:TCL, receive args as an argument and pass it to another procedureTCL,接收 args 作为参数并将其传递给另一个过程
【发布时间】:2016-02-16 17:08:27
【问题描述】:

我尝试在 TCL 中执行以下操作并收到以下错误 “列表必须是偶数个元素”,因为 $args 在传递给 B 时被视为一个列表。

有没有将 $args 传递给 B 的巧妙方法?

proc A {a args} {        
    #call B and pass it args
    B 2 $args
}

proc B {b args} {
    set options(-flag1)  0
    set options(-option) serial

    array set options $args
    #use options
}

【问题讨论】:

  • 你在使用array set命令吗?分享完整代码。
  • 你去@Dinesh 我已经更新了代码

标签: tcl tk


【解决方案1】:

试试这个:

B 2 {*}$args

如果我们稍微简化一下程序:

proc A args {
    puts [info level 0]
    B $args
}
proc B args {
    puts [info level 0]
}

如果我们用一些值调用AB 将接收打包在列表中的这些值。此列表是 args 中的单个项目,不适合传递给 array set,因为该命令需要一个偶数大小的列表。

% A a b c d
A a b c d
B {a b c d}

B的调用改为:

proc A args {
    puts [info level 0]
    B {*}$args
}

现在,如果我们调用AA 的每个参数都将成为B 的不同参数,$args 现在可以用作array set 的参数。

% A a b c d
A a b c d
B a b c d

正如 nurdglaw 所指出的,Tcl 8.4 或更早版本没有{*} 语法,这意味着必须使用eval 来调用B。一种方法是

eval [linsert $args 0 B]

但也可以使用安全性稍差的(可能导致参数结构丢失)

eval B $args

不再支持 Tcl 8.4,完全有理由升级到 8.5 或 8.6。

文档:evalinfolinsertprocputs{*}

【讨论】:

  • 只是点最后一个 i... {*} 运算符是在 Tcl 8.5 中引入的。如果您真的必须使用较早的版本,则需要通过更不透明的eval [linsert $args 0 B] 调用 B - 它会创建一个包含 B 和所有单独参数的新列表,然后将该列表作为命令进行评估。
  • 鉴于args 保证是正确的列表,您可以使用eval [list B] $args。它比linsert 版本更易于理解。但是肯定升级,因为 8.4 不再支持了。
  • 该死!!彼得和@nurdglaw,我感激不尽。拯救了我的一天。关于版本,我使用的是 8.3。我刚开始为一家大公司工作,我不拥有代码。我认为他们不会想要很快升级。但我会问。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 2013-10-13
相关资源
最近更新 更多