【问题标题】:Passing list to Tcl procedure将列表传递给 Tcl 过程
【发布时间】:2010-12-08 11:27:14
【问题描述】:

将列表传递给 Tcl 过程的规范方法是什么?

如果我能得到它,我真的很喜欢它,以便列表自动扩展为可变数量的参数。

这样的话:

set a {b c}
myprocedure option1 option2 $a

myprocedure option1 option2 b c

是等价的。

我确定我以前看过这个,但我在网上的任何地方都找不到。任何使这两种情况等效的帮助(和代码)将不胜感激。

这是否被认为是标准的 Tcl 约定。或者我什至是在叫错树?

【问题讨论】:

  • 你会在你的好问题的某处添加“unwrap”(最好是“unwrap arguments”)这个词吗?我很难找到它:-)

标签: list arguments tcl


【解决方案1】:

这取决于您使用的 Tcl 版本,但是: 对于 8.5:

set mylist {a b c}
myprocedure option1 option2 {*}$mylist

对于 8.4 及以下版本:

set mylist {a b c}
eval myprocedure option1 option2 $mylist
# or, if option1 and 2 are variables
eval myprocedure [list $option1] [list $option2] $mylist
# or, as Bryan prefers
eval myprocedure \$option1 \$option2 $mylist

【讨论】:

  • ... 虽然我个人认为 \$option1 \$option2 比 [list $option1] [list $optio2] 更可取。它更密切地显示了意图 - 您的意图不是创建单元素列表,您的意图是防止(或防止)对这些变量进行额外的一轮替换。
  • 在 8.4 及以下版本中执行此操作的规范方法是:eval [linsert $mylist 0 myprocedure options1 option2]
  • 我不同意这是规范的(但也许我们有不同的规范?)。它可以说是最安全的,但它的可读性不如 \$option1 \$option2 并且再次有点模糊了你真正想要完成的事情。
  • 应该注意的是,8.5(及更高版本)的扩展语法是强烈首选的,因为在此之前,即使是经验丰富的专家也会遇到麻烦。它也可能更快。
  • Tcl8.5 是从 Python 借用星号 (*) 还是反过来?
【解决方案2】:

要扩展 RHSeeger 的答案,您可以使用特殊的 args 参数对 myprocedure 进行编码,如下所示:

proc myprocedure {opt1 opt2 args} {
    puts "opt1=$opt1"
    puts "opt2=$opt2"
    puts "args=[list $args]" ;# just use [list] for output formatting
    puts "args has [llength $args] elements"
}

【讨论】:

  • 我不同意你必须编写 myprocedure 来获取可变数量的参数(即,使用“args”)。您是否这样做完全取决于您是否需要它来接受可变数量的输入,而不是取决于某个特定调用者碰巧如何获得它的输入。
【解决方案3】:

请注意,将您的命令传递给catch 也可以解决此问题:

set a {b c}
if [catch "myprocedure option1 option2 $a"] {
    # handle errors
}

这可能只应在您想在代码中处理 myprocedure 中的错误时使用,这样您就不必担心重新抛出任何被捕获的错误。

【讨论】:

    猜你喜欢
    • 2016-07-12
    • 1970-01-01
    • 2013-04-24
    • 2019-12-03
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    相关资源
    最近更新 更多