4

我对 tcl 有点陌生,但我必须编写一个如下所示的 proc:

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

我这样称呼proc:TestVerb Switch"This is used for..."

proc 在另一个文件中,proc 调用在另一个文件中。它们似乎来源正确,因为如果我不使用,我会得到所需的输出,$argc但是一旦我使用其中一个,$argv或者$argc我得到以下编译错误:Can't read $argv/$argcno such variable

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

4

3 回答 3

1

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

  • 如果 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:在调用您的过程时,解释器已经检查过它。

  • 和全局变量控制从操作系统传递到执行 Tcl 脚本的 Tcl 解释器argc程序的内容argv

    也就是说,当你调用类似

    $ 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 6foo xb

在这样的 proc 中,您可以使用普通的列表命令(如llengthlindex)来检查args. 例如,调用foo 1 2 3 4 5 6将设置args为您通过调用获得的相同值[list 3 4 5 6]

于 2015-01-28T18:41:16.323 回答
1

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

global argc argv

或使用完全合格的版本。

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

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

set allArguments [info level 0]

你通常不需要它。在声明您的程序时,您绝对不需要它,例如:

proc TestVerb { Data Data_txt } {
    ...
}
于 2015-01-28T15:20:28.350 回答
0

正如上面已经提到的,argv并且argc不引用本地过程参数,默认情况下,Tcl proc 中的参数数量是固定的。如果要使用变量列表,可以编写args

proc TestVerb {args} {}

args可以视为普通列表。如果要测试可以使用的参数数量llength并用于lassign拆分参数列表:

proc TestVerb {args} {
    if {[llength $args] != 2} {
        message
        return
    }
    lassign $args Data Data_txt
    ....
}
于 2019-01-16T10:19:23.783 回答