我想用一些选项创建tcl程序。我知道带有参数和可选参数的程序,但不知道选项。例如,如果我按照以下三种方式调用我的过程算法(-add用于加法,-sub用于减法):
1) arith 10 5
2) arith -add 10 5 or arith 10 5 -add
3) arith -sub 10 5 or arith 10 5 -sub
分别输出应为1)15(默认情况下应添加),2)15,3)5
如何在Tcl中编写此过程?我是tcl的新手,请为我推荐一些Tcl的在线资料或书籍。
答案 0 :(得分:3)
说到选项,使用偶数个参数
是个好主意 -op add -values {10 5}
-op sub -values {10 5}
有了这个,您可以将参数放入数组中,
array set aArgs $args
其中args
只是传递给过程的参数。
proc arith {args} {
if {[catch {array set aArgs $args} err]} {
puts "Error : $err"
return 0
}
if {![info exists aArgs(-op)] || ![info exists aArgs(-values)] || [llength $aArgs(-values)]!=2} {
puts "Please pass valid args"
return 0
}
set x [lindex $aArgs(-values) 0]
set y [lindex $aArgs(-values) 1]
switch $aArgs(-op) {
"add" {
puts [expr {$x+$y}]
}
"sub" {
puts [expr {$x-$y}]
}
}
}
arith -op add -values {10 5}
答案 1 :(得分:3)
复杂的参数解析可以使用cmdline
package来完成,{{3}}是Tcllib的一部分。键命令是::cmdline::getoptions
,它从变量中提取选项并返回描述它们的字典。它还修改变量,使其仅包含遗留的参数。
package require cmdline
proc arith args {
set options {
{op.arg "add" "operation to apply (defaults to 'add')"}
}
array set parsed [::cmdline::getoptions args $options]
if {[llength $args] != 2} {
return -code error "wrong # args: must be \"arith ?-op operation? x y\""
}
switch $parsed(op) {
add {return [::tcl::mathop::+ {*}$args]}
sub {return [::tcl::mathop::- {*}$args]}
default {
return -code error "Unknown -op \"$parsed(op)\": must be add or sub"
}
}
}
演示用法(包括一些错误情况):
% arith
wrong # args: must be "arith ?-op operation? x y"
% arith 2 3
5
% arith -op sub 2 3
-1
% arith -op mult 2 3
Unknown -op "mult": must be add or sub
要注意的主要事情是,选项描述符采用选项的名称,而不带前导-
和带 .arg
最后,如果你想传递一个参数。
答案 2 :(得分:0)
在此示例中...我假设运算符是第一个或最后一个选项。该值为-add
或add
。只需进行更改即可。
计算中有一个优化...使用lrange和:: mathop ::。
proc arith args {
if {[llength $args] != 3} {
return -code error "wrong # args: must be \"arith ?-op operation? x y\""
}
set isadd [lsearch $args add]
set issub [lsearch $args sub]
if {$isadd != -1 && $issub == -1} {
return [expr [lindex $args 1] + [lindex $args [expr $isadd == 0 ? 2: 0]]]
}
if {$issub != -1 && $isadd == -1} {
return [expr [lindex $args [expr $issub == 0 ? 1: 0]] - [lindex $args [expr $issub == 0 ? 2: 1]]]
}
return -code error "Unknown -op must be add or sub"
}
示例:
#arith add 1 2 3
#arith add sub 2
puts [arith add 1 2]
puts [arith 1 2 add]
puts [arith sub 1 2]
puts [arith 1 2 sub]
两个错误示例被注释掉了,因为我需要一个陷阱...但这实际上取决于全局,以及它的预期可重用性。
proc arith args {
if {[llength $args] != 3} {
return -code error "wrong # args: must be \"arith ?-op operation? x y\""
}
set isadd [lsearch $args -add]
set issub [lsearch $args -sub]
if {$isadd != -1 && $issub == -1} {
return [::tcl::mathop::+ {*}[lrange $args [expr $isadd == 0] [expr ($isadd == 0) + 1]]]
}
if {$issub != -1 && $isadd == -1} {
return [::tcl::mathop::- {*}[lrange $args [expr $issub == 0] [expr ($issub == 0) + 1]]]
}
return -code error "Unknown -op must be add or sub"
}