Tcl $argc 和 $argv 变量

Tcl $argc and $argv variables

我是 tcl 的新手,但我必须编写一个如下所示的过程:

proc TestVerb { Data Data_txt } {
VERBATIM [format "// Data: $Data - $Data_txt"]
if { $argc == 2} {
    VERBATIM {// SUCCESS //}
else {
    exit 1
}

我这样调用过程:TestVerb Switch"This is used for..."

proc 在不同的文件中,proc 调用在另一个文件中。它们的来源似乎正确,因为如果我不使用 $argc 我会得到所需的输出,但是一旦我使用 $argv$argc 我会收到以下编译错误:无法读取 $argv/$argc 没有这样的变量

如果我用 $::argc$::argv 引用这个变量,结果是不正确的。 $argv 为空且 $argc 为 0

argcargv变量是全局变量(当它们有任何特殊含义时)。在一个过程中,它们并不特别 根本 除非你说:

global argc argv

或使用完全合格的版本。

对于您的过程,除非您传入正确数量的参数,否则您将收到一条错误消息(由过程调用机制生成)。您不需要自己检查(除非您使用带默认值的形式参数或特殊的 args 变量——注意拼写——在形式参数的末尾。

要获取传递给您的过程的参数的确切列表,请使用:

set allArguments [info level 0]

您通常不需要它。你绝对在声明你的过程时不需要它:

proc TestVerb { Data Data_txt } {
    ...
}

您在这里似乎做出了两个错误的假设:

  • 如果 proc 在其定义中不使用特殊参数 args(有关更多信息,请参见下文),它只接受固定数量的参数——与参数数量完全匹配在其定义中使用。每个调用都由解释器检查,任何参数数量无效的调用都将在到达过程代码本身之前失败。

    自己看看:

    % proc foo {a b c} {}
    % foo
    wrong # args: should be "foo a b c"
    % foo 1
    wrong # args: should be "foo a b c"
    % foo 1 2 3 4
    wrong # args: should be "foo a b c"
    % foo 1 2 3
    %
    

    换句话说,不要试图检查传递给您的参数的数量 proc:当您的过程被调用时,解释器已经检查过了。

  • argcargv 全局变量控制什么从操作系统传递到 Tcl 解释器 程序 正在执行你的Tcl 脚本。

    也就是说,当你调用类似

    的东西时
    $ tclsh myscript.tcl foo bar
    

    名为 argc 的变量将包含 2,而 argv 将设置为包含两个字符串的列表——"foo" 和 "bar"。

    换句话说,这些变量与个别程序无关。


关于 args 特殊参数:如果程序使用单词 "args" 作为其参数的 最后一个 或将其作为唯一参数,然后这个参数变成一个列表,它消耗任意数量(包括零)的实际参数。

所以你可以做到

proc foo {a b args} {}

然后你的 foo 过程可以像 foo 1 2foo 1 2 3 4 5 6 一样被调用,但不像 foo x (因为 b 正式论证)。

在这样的过程中,您可以使用普通的列表命令(如 llengthlindex)来检查 args 中包含的任何内容。例如,调用 foo 1 2 3 4 5 6 会将 args 设置为您通过调用 [list 3 4 5 6].

获得的相同值

如上所述,argvargc 不引用本地过程参数, 默认情况下,Tcl proc 中的参数数量是固定的。如果要使用变量列表,可以这样写args:

proc TestVerb {args} {}

args 可以当作一个普通列表。如果要测试参数的数量,可以使用 llength 并使用 lassign 拆分参数列表:

proc TestVerb {args} {
    if {[llength $args] != 2} {
        message
        return
    }
    lassign $args Data Data_txt
    ....
}