我怎样才能安全地处理可选参数
我正在写一个proc来在输出文件中创建一个头文件。我怎样才能安全地处理可选参数
目前它需要一个可选参数,这是一个可能的标题注释。
我已经结束了编码这是一个可选参数
proc dump_header { test description {comment = ""}}
,但想知道怎样才能达到使用ARGS相同
proc dump_header { test description args }
这是很容易检查ARGS是一个空白参数($ args ==“”),但如果传递多个参数则不能很好地处理 - 而且我仍然需要负面检查。
您的proc定义不正确(您会收到错误消息too many fields in argument specifier "comment = """
)。应该是:
proc dump_header { test description {comment ""}} {
puts $comment
}
如果你想使用args
,你可以检查它的llength
:
proc dump_header {test desc args} {
switch -exact [llength $args] {
0 {puts "no comment"}
1 {puts "the comment is: $args"}
default {
puts "the comment is: [lindex $args 0]"
puts "the other args are: [lrange $args 1 end]"
}
}
}
你可能也想通过名称 - 值对列表:
proc dump_header {test desc options} {
# following will error if $options is an odd-length list
array set opts $options
if {[info exists opts(comment)]} {
puts "the comment is: $opts(comment)"
}
puts "here are all the options given:"
parray opts
}
dump_header "test" "description" {comment "a comment" arg1 foo arg2 bar}
某些人更喜欢args
与名称 - 值对(a la Tk)的组合
proc dump_header {test desc args} {
# following will error if $args is an odd-length list
array set opts $args
if {[info exists opts(-comment)]} {
puts "the comment is: $opts(-comment)"
}
parray opts
}
dump_header "test" "description" -comment "a comment" -arg1 foo -arg2 bar
谢谢,这可能是不必要的。 对于其他情况,我认为我更喜欢名称 - 值对......但在这种情况下,我想您的答案将转换为“处理所有您必须视为数组的情况”。这很好。 – itj 2010-03-01 13:39:13
这是CMDLINE文档的例子:
set options {
{a "set the atime only"}
{m "set the mtime only"}
{c "do not create non-existent files"}
{r.arg "" "use time from ref_file"}
{t.arg -1 "use specified time"}
}
set usage ": MyCommandName \[options] filename ...\noptions:"
array set params [::cmdline::getoptions argv $options $usage]
if { $params(a) } { set set_atime "true" }
set has_t [expr {$params(t) != -1}]
set has_r [expr {[string length $params(r)] > 0}]
if {$has_t && $has_r} {
return -code error "Cannot specify both -r and -t"
} elseif {$has_t} {
...
}
所以,你的情况,你只是在上面的例子中使用args
代替argv
。
应该明确提到args
是Tcl中的一个特殊词,它在参数列表的末尾使用时包含所有其余参数的列表。如果没有给出args
,则不会产生错误(与任何其他变量名称不同,后者将被视为必需参数)。
我一直在寻找工作的好听点是(类似格伦的最后一个例子)的方式也有类似的Python的kwargs
(可选的键值对参数)的功能,以及东西:
proc my_proc {positional_required1 {positional_optional1 "a_string"} args} {
# Two optional arguments can be given: "opt1" and "opt2"
if {![string equal $args ""]} {
# If one or more args is given, parse them or assign defaults.
array set opts $args
if {[info exists opts(opt1)]} { set opt1 $opts(opt1) } else { set opt1 0 }
if {[info exists opts(op2)]} { set opt2 $opts(opt2) } else { set opt2 -1 }
} else {
# If no args are given, assign default values.
set op1 0
set op2 -1
}
# DO STUFF HERE
}
,并且可以所谓的喜欢:
my_proc "positional_required1_argument"
# OR
my_proc "positional_required1_argument" "a_string"
# OR
my_proc "positional_required1_argument" "a_string" opt1 7
# OR
my_proc "positional_required1_argument" "a_string" opt1 7 opt2 50
# etc.
一个潜在的不利因素(如我目前实现了它)是,如果用户通过未经批准的键值选项,没有错误。
如果你的proc被超过3个参数调用,你想要做什么:dump_header mytest mydesc {One comment} somethingelse?把somethingelse作为另一种评论,以其他方式处理? – 2010-02-26 12:58:36
将$ args与空字符串进行比较是错误的。参数是一个列表,而不是一个字符串。 – 2010-02-26 18:16:12
好吧,它本身并没有错,因为它会创建一个字符串表示,但是如果您要将它作为列表反正 – 2010-03-01 11:29:26