tcl
Аргументы процедуры
Поиск…
замечания
Ссылки: proc
Расширение аргумента (раздел 5)
Процедура, которая не принимает аргументы
proc myproc {} {
puts "hi"
}
myproc
# => hi
Пустой список аргументов (второй аргумент после имени процедуры, «myproc») означает, что процедура не будет принимать аргументы.
Процедура, допускающая два аргумента
proc myproc {alpha beta} {
...
set foo $alpha
set beta $bar ;# note: possibly useless invocation
}
myproc 12 34 ;# alpha will be 12, beta will be 34
Если список аргументов состоит из слов, это будут имена локальных переменных в процедуре, и их начальные значения будут равны значениям аргументов в командной строке. Аргументы передаются по значению, и все, что происходит с значениями переменной внутри процедуры, не будет влиять на состояние данных вне процедуры.
Процедура, которая принимает переменное число аргументов
### Definition
proc myproc {alpha {beta {}} {gamma green}} {
puts [list $alpha $beta $gamma]
}
### Use
myproc A
# => A {} green
myproc A B
# => A B green
myproc A B C
# => A B C
Эта процедура принимает один, два или три аргумента: параметры, чьи имена являются первым элементом в списке из двух элементов, являются необязательными. Переменные параметров ( alpha , beta , gamma ) получают столько значений аргументов, сколько доступно, назначенных слева направо. Переменные параметров, которые не получают значения аргументов, вместо этого получают свои значения из второго элемента в списке, в котором они были частью.
Обратите внимание, что необязательные аргументы должны появляться в конце списка аргументов. Если аргумент N-1 является необязательным, аргумент N также должен быть необязательным. Если в случае, когда у пользователя есть аргумент N, но не аргумент N-1 , значение аргумента N-1 по умолчанию должно быть явно указано перед аргументом N при вызове процедуры.
myproc A B C D
# (ERROR) wrong # args: should be "myproc alpha ?beta? ?gamma?"
Процедура не принимает более трех аргументов: обратите внимание, что автоматически создается полезное сообщение об ошибке, описывающее синтаксис аргумента.
Процедура, которая принимает любое количество аргументов
proc myproc args { ... }
proc myproc {args} { ... } ;# equivalent
Если имя args специального параметра - последний элемент в списке аргументов, он получает список всех аргументов в этой точке в командной строке. Если их нет, список пуст.
Там может быть аргументы, в том числе факультативных, до args :
proc myproc {alpha {beta {}} args} { ... }
Эта процедура будет принимать один или несколько аргументов. Первые два, если они присутствуют, будут потребляться alpha и beta : список остальных аргументов будет присваиваться args .
Процедура, которая принимает имя / ссылку на переменную
proc myproc {varName alpha beta} {
upvar 1 $varName var
set var [expr {$var * $alpha + $beta}]
}
set foo 1
myproc foo 10 5
puts $foo
# => 15
В этом конкретном случае процедуре присваивается имя переменной в текущей области. Внутри процедуры Tcl такие переменные автоматически не видны, но команда upvar может создавать псевдоним для переменной с другого уровня стека: 1 означает уровень стека вызывающего, # 0 означает глобальный уровень и т. Д. В этом случае уровень стека 1 и имя foo (из переменной параметра varName ) позволяют upvar найти эту переменную и создать псевдоним var . Каждая операция чтения или записи в var также происходит с foo на уровне стека вызывающего.
Синтаксис {*}
Иногда у вас есть список, но команда, которую вы хотите передать элементам в списке, чтобы требовать, чтобы каждый элемент был отдельным аргументом. Например: команда winfo children возвращает список окон, но команда destroy принимает только последовательность аргументов имени окна.
set alpha [winfo children .]
# => .a .b .c
destroy $alpha
# (no response, no windows are destroyed)
Решение состоит в использовании синтаксиса {*} :
destroy {*}[winfo children .]
или же
destroy {*}$alpha
Синтаксис {*} состоит в том, чтобы принять следующее значение (без пробелов между ними!) И сплайсировать элементы в этом значении в командной строке, как если бы они были отдельными аргументами.
Если следующее значение является пустым списком, ничто не сплавляется в:
puts [list a b {*}{} c d]
# => a b c d
Если есть один или несколько элементов, они вставлены:
puts [list a b {*}{1 2 3} c d]
# => a b 1 2 3 c d