【问题标题】:In TCL,can we pass parameters in this way?在TCL中,我们可以这样传递参数吗?
【发布时间】:2012-03-16 11:36:13
【问题描述】:

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

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的默认值是不是“罗纳尔多”?是这样,为什么我们需要在我们的 proc 中有“全局名称”命令?

【问题讨论】:

    标签: tcl parameter-passing


    【解决方案1】:

    目前的情况是行不通的; $name 根本不会被评估,因此默认值将是这五个字符。

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

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

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

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

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

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

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

    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% 的情况。)

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

    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
        }
        ...
    }
    

    如您所见,这是相当冗长的......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 2016-05-26
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      相关资源
      最近更新 更多