Tcl Syntactic 之 const 和 tuple
Const 变量
proc const#check {name args} {
return -code error -level 2 "const variable `\$$name` is readonly!"
}
proc const {name value} {
upvar 1 $name var
set var $value
trace add variable var write [list tuple#check $name]
}
const abc 123 ;# 定义一个常量
set abc 456
Tuple
A tuple is a readonly list.
proc tuple#check {name args} {
return -code error -level 2 "tuple `\$$name` is readonly!"
}
proc tuple {name value} {
upvar 1 $name var
set var $value
trace add variable var write [list tuple#check $name]
}
tuple abc {1 2 3 4} ;# 定义一个 tuple
set abc 456
#Error: tuple `$abc` is readonly!
利用 const 避免函数参数覆盖
下面的proc
有一个参数name
容易由于不小心被局部变量覆盖。
proc hello {name} {
foreach {name} {a b c} {
puts $name
}
puts "name = $name"
}
hello "tcler.net"
解决这个问题,一种方法是通过命名约定。比如 Vim Script 里面,参数变量通过 a:name
的形式来访问——其中的a:
表示参数。
另一种思路是让参数变量变成只读的。语义上类似于这样
proc const#alert {name} {
return -code error -level 2 "argument `\$$name` is readonly!"
}
proc const {name} {
upvar 1 $name var
trace add variable var write [list const#alert $name]
}
proc hello {name} {
const name
foreach {name} {a b c} {
puts $name
}
puts "name = $name"
}
让 trace 更简单
trace add variable $name write {
return -code error "variable $name is readonly"
}
trace add variable $name write [lamda {name args} {
return -code error "variable $name is readonly"
} $name]