В TCL мы можем передать параметры таким способом? - PullRequest
5 голосов
/ 16 марта 2012

У меня есть вопрос о передаче параметров в 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»? и перед тем, как мы выполним команду "global name", по умолчанию значение player_name равно "Ronaldo"? так зачем нам нужна команда "global name" в нашей процедуре?

1 Ответ

7 голосов
/ 16 марта 2012

Это не будет работать, как есть; $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
    }
    ...
}

Обратите внимание, что я использовал полное имя переменной там. Есть и другие способы получить это имя (например, с global, с upvar, с variable, ...)

Место, где все становится сложнее, это когда у вас нет подходящего дозорного значения вообще . В этот момент вы должны увидеть, сколько аргументов было на самом деле предоставлено:

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

Как видите, это довольно скучно ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...