在TCL中,我们可以通过这种方式传递参数吗? [英] In TCL,can we pass parameters in this way?

查看:73
本文介绍了在TCL中,我们可以通过这种方式传递参数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于在 Tcl 中传递参数关于以下代码的问题:

I have a question about passing parameters in Tcl regarding to the following code:

set name "Ronaldo"

proc GET_PLAYER_INFO {player_id {player_name "$name"}} {
    global name
    puts $player_name
}

对于上面的代码,我们有一个全局变量name",在proc GET_PLAYER_INFO的参数列表中,参数player_name的默认值设置为$name"?如果name的值为ronaldo",就已经是双引号了,是否需要在参数列表中加上双引号: player_name "$name"?而在我们执行全局名称"命令之前,player_name 的默认值是Ronaldo"吗?是这样,为什么我们需要在我们的 proc 中有全局名称"命令?

regarding to the code above, we have a global variable "name", and in the parameter list of proc GET_PLAYER_INFO, the default value of parameter player_name is set to "$name"? if the value of name is "ronaldo", it is already double quotation,do we need to put double quotation in the parameters list like this: player_name "$name"? and before we execute the "global name" command, is the default value of player_name is "Ronaldo"? is so, why we need to have "global name" command in our proc?

推荐答案

这不会奏效;$name 根本不会被评估,所以默认值将是那些文字五个字符.

That won't work as it stands; the $name won't be evaluated at all so the default will be those literal five characters.

如果您在创建过程时绑定了默认值,您可以这样做:

If you're binding the default value at the time you create the procedure, you'd do it like this:

proc GET_PLAYER_INFO [list player_id [list player_name $name]] {
    ...
}

也就是说,proc 的参数只是你可以用 Tcl 命令和替换来构造的普通东西.这是 Tcl 的一大优点.

That is, the arguments to proc are just normal things you can construct with Tcl commands and substitutions. This is one of the great things about Tcl.

但是,如果您想在调用过程时计算 $name,则必须采用不同的方法.如果您有某种永远不会用于玩家名称的值(例如,空字符串),那么这很容易:

However, if you're wanting to evaluate that $name at the time the procedure is called, you've got to do it differently. If you've got some kind of value that will never be used for the player name (e.g., the empty string) then it's pretty easy:

proc GET_PLAYER_INFO {player_id {player_name ""}} {
    if {$player_name eq ""} {
        set player_name $::name
    }
    ...
}

请注意,我在那里使用了完全限定的变量名称.还有其他方法可以获得该名称(例如,使用 globalupvarvariable,...)

Note that I've used the fully-qualified variable name there. There are other ways to get that name too (e.g., with global, with upvar, with variable, …)

事情变得棘手的地方是根本没有合适的哨兵值.此时,您必须查看实际提供了多少个参数:

The place where things get tricky is when you've not got a suitable sentinel value at all. At that point, you have to see how many arguments were actually supplied:

proc GET_PLAYER_INFO {player_id {player_name ""}} {
    if {[llength [info level 0]] == 2} {
        set player_name $::name
    }
    ...
}

命令info level 0 返回当前过程调用的参数词的完整列表.这包括 GET_PLAYER_INFO 本身,并且在对上述定义的有效调用中将是长度为 2 或 3 的列表.一旦列表可用,在 llength 和数字比较中检查其长度是一项微不足道的练习.(不过,使用哨兵值更容易,并且在 99.99% 的情况下都有效.)

The command info level 0 returns the full list of argument words to the current procedure call. This includes the GET_PLAYER_INFO itself and would be a list of length 2 or 3 in a valid call to the definition above. Once the list is available, checking its length is a trivial exercise in llength and numeric comparison. (Using a sentinel value is easier though, and works in 99.99% of cases.)

最后一个选项是使用特殊的 args 形式参数并手动进行解析:

The final option is to use the special args formal parameter and do the parsing manually:

proc GET_PLAYER_INFO args {
    if {[llength $args] < 1 || [llength $args] > 2} {
        return -code error "wrong # args: should be \"GET_PLAYER_INFO player_id ?player_name?\""
    }
    set player_id [lindex $args 0]
    if {[llength $args] > 1} {
        set player_name [lindex $args 1]
    } else {
        set player_name $::name
    }
    ...
}

正如你所看到的,这是相当冗长的......

As you can see, this is rather long-winded...

这篇关于在TCL中,我们可以通过这种方式传递参数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆