使用命名参数调用TCL proc

时间:2015-03-19 16:57:48

标签: tcl

鉴于此过程:

proc foo {{aa "a"} {bb "b"} cc} {
  echo $cc
}

是否可以调用proc foo并仅传递cc的值?此外,是否可以通过名称明确地将值传递给cc

我所看到的一切都暗示所有论据必须按位置传递。

3 个答案:

答案 0 :(得分:7)

我会像Tk那样做:

proc foo {cc args} {
    # following will error if $args is an odd-length list
    array set optional [list -aa "default a" -bb "default b" {*}$args]
    set aa $optional(-aa)
    set bb $optional(-bb)

    puts "aa: $aa"
    puts "bb: $bb"
    puts "cc: $cc"
}

然后

% foo
wrong # args: should be "foo cc ..."
% foo bar
aa: default a
bb: default b
cc: bar
% foo bar -bb hello -aa world
aa: world
bb: hello
cc: bar

答案 1 :(得分:0)

程序的参数按位置传递。使用两个元素列表作为参数列表的一个组成部分,例如{aa a},是提供默认值。但是正如手册所说:

  

默认值后跟非默认参数的参数成为必需参数。在8.6中,这将被视为错误。

因此,大多数人设计他们的过程接口来放置在参数列表末尾提供默认值的参数。

模拟命名参数的一种方法是将过程设计为采用单个参数,该参数是字典值,其中字典的键是参数的名称。例如,

proc foo {a} {
    if {[dict exists $a cc]} {
        puts [dict get $a cc]
    }
}

foo [dict create cc "this is the cc argument value"]

如果您不介意确定提供哪些可选参数以及构建字典来调用该过程的单调乏味,那么您可以通过这种方式模拟命名参数,并在为过程提供参数方面实现一定的灵活性。我自己经常不经常使用这种技术。我发现更仔细地设计过程接口更容易。但有时情况需要各种各样的事情。

答案 2 :(得分:0)

你可以使用类型闪烁来避免构造dict ..这给出了一个有趣的简单和直观的调用。将dict的列表表示传递给proc例如:

  proc foo {a} {
      if {[dict exists $a cc]} {
          puts [dict get $a cc]
      }
  }

  foo {cc "this is the cc argument value" dd "this is the value of dd}