如何使用选项创建Tcl过程?

时间:2015-12-02 06:31:30

标签: tcl procedure options

我想用一些选项创建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的在线资料或书籍。

3 个答案:

答案 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)

在此示例中...我假设运算符是第一个或最后一个选项。该值为-addadd。只需进行更改即可。

计算中有一个优化...使用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"
}