如何使用默认值和选项编写tcl过程?

时间:2016-08-31 23:58:45

标签: tcl

我正在尝试编写一个执行以下操作的tcl过程 -

proc myProc {arg1 def1} {arg2 def2} {
...
...
}

tcl> myProc -arg1 val1 -arg2 val2
arg1 variable has val1
arg2 variable has val2

tcl> myProc -arg1 val1
arg1 variable has val1
arg2 variable has def2

tcl> myProc -?
myProc -arg1 <value1> -arg2 <value2>
arg1 - required argument [default value is 10]
arg2 - optional argument [default value is 20]
help - print this message
?    - print this message

这可能在tcl中吗?

我查了一些问题,我看到的是question。这部分完成了我的要求,但我无法找到任何可以帮助我解决问题的方法。请指导我!

4 个答案:

答案 0 :(得分:1)

您可以使用Tcllib模块cmdline。在wiki上,您可以找到如何将该模块与proc。

一起使用的示例
proc printdata args {
    array set param [::cmdline::getoptions args {\
                    {page.arg  1 "current page"}
                    {pages.arg 1 "number of pages"}
                    } "printdata ?options? Data"]
    if {1 != [llength $args]} {
            return -code error "No data given"
    }
    set param(data) [lindex $args 0]
    # processing here
    parray param
}

% printdata -pages 2 -- "--Head data to print--"
param(data)  = --Head data to print--
param(page)  = 1
param(pages) = 2

% printdata -?
printdata ?options? Data
 -page value          current page <1>
 -pages value         number of pages <1>
 -help                Print this message
 -?                   Print this message

答案 1 :(得分:1)

仔细阅读proc手册页:参数列表必须是单个列表。你在想这个:

% proc myproc {{a 42} {b 54}} { puts "a=$a b=$b" }
% myproc
a=42 b=54
% myproc 1
a=1 b=54
% myproc 1 2
a=1 b=2

请注意,第一个参数已分配给a - 您无法为b提供值,并使用此方法使用a的默认值。

要使用类似命令行的选项,最简单的方法是:

% proc myproc {args} {
    array set data [list -a 42 -b 54 {*}$args]
    puts "a=$data(-a) b=$data(-b)"
}
% myproc
a=42 b=54
% myproc -a 1
a=1 b=54
% myproc -b 2
a=42 b=2
% myproc -b 2 -a 3
a=3 b=2
% myproc -c 4
a=42 b=54

此方法的一个问题是您必须传递偶数个参数,否则array set将引发错误:

% myproc 12
list must have an even number of elements

答案 2 :(得分:1)

我今年写了一个实用功能。参数与proc具有相同的语法,但它会生成以您描述的方式工作的过程。代码很简单:

proc optproc {name args script} {
    proc $name args [
        string map [list ARGS $args SCRIPT $script] {
            foreach var {ARGS} {
                set [lindex $var 0] [lindex $var 1]
            }

            foreach {var val} $args {
                set [string trim $var -] $val
            }

            SCRIPT
        }
    ]
}

上面的代码基本上是调用proc,并将两个foreach循环注入到函数体中以处理参数。

有了这个,您可以声明您的功能:

optproc myProc {{arg1 def1} {arg2 def2}} {
    # you can use arg1 and arg2 just like a regular proc:

    puts $arg1
    puts $arg2
}

然后您可以按照自己的方式使用

myProc                      ;# default values for arg1 and arg2
myProc -arg1 foo            ;# default values for arg2
myProc -arg2 bar            ;# default values for arg1
myProc -arg1 foo -arg2 bar

有关此内容的更多信息和讨论,您可以阅读维基页面:http://wiki.tcl.tk/20066

对于更灵活的proc参数处理,您可以使用while循环:http://wiki.tcl.tk/16032

答案 3 :(得分:0)

感谢大家的宝贵意见。我写了以下代码,帮助我实现我想要的目标 -

<强> 代码

proc argsParser args {

    set args [string map { - "" } $args]

    if {[expr [llength $args] % 2] != 0 } {
        puts "Wrong Arguments :: $args "
        return "For Help :: argsParser -?";
    }

    switch $args {
        h -
        help -
        ? { puts "Usage :: argParser -arg1 val1 -arg2 val2" 
              puts "arg1 :: Number"
              puts "arg2 :: Number"
        }
        default {
            set arg1 10 ;
            set arg2 20 ;

            set args [string map { - "" } $args]
            for {set i 0} {$i < [llength $args]} { incr i 2} {
                set a [lindex $args $i]
                if { $a != "arg1" && $a != "arg2" } {
                    return "Unknown Args :: $a - For Help :: argsParser -?";
                }
                set b [lindex $args [expr $i+1]]
                set $a $b 
            }

            puts "arg1 - $arg1"
            puts "arg2 - $arg2"
        }   
    }   
}

<强> 结果

tcl> argsParser -arg1 20 -arg4 40
Unknown Args :: arg4 - For Help :: argsParser -?

tcl> argsParser -arg1 20 -arg2 40
arg1 - 20
arg2 - 40