2012-03-16 3 views
5

У меня есть вопрос о передаче параметров в Tcl относительно к следующему коду:В TCL мы можем передавать параметры таким образом?

set name "Ronaldo" 

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

относительно приведенный выше код, мы имеем глобальную переменную «имя», и в списке параметров Proc GET_PLAYER_INFO, по умолчанию Значение параметра player_name установлено на «$ name»? если значение имени «ronaldo», это уже двойная кавычка, нам нужно поместить двойную кавычку в список параметров следующим образом: player_name «$ name»? и до того, как мы выполним команду «global name», значением по умолчанию для player_name является «Ronaldo»? так почему нам нужно иметь команду «global name» в нашем proc?

ответ

7

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

Как вы можете видеть , это довольно затянуто ...

Смежные вопросы