Tcl:使用unknown命令包含点表示法过程
从命令/参数结构的角度来看,Tcl语法非常简单且一致。有时我会怀念其他语言如ruby的点表示法。在ruby中,您可以更正如下内容:Tcl:使用unknown命令包含点表示法过程,tcl,Tcl,从命令/参数结构的角度来看,Tcl语法非常简单且一致。有时我会怀念其他语言如ruby的点表示法。在ruby中,您可以更正如下内容: -199.abs # => 199 "ice is nice".length # => 11 "ruby is cool.".index("u")
-199.abs # => 199
"ice is nice".length # => 11
"ruby is cool.".index("u") # => 1
"Nice Day Isn't It?".downcase.split("").uniq.sort.join # => " '?acdeinsty"
在中,有一些关于如何使用未知命令修改语言的想法,例如:
proc know {cond body} {
proc unknown {args} [string map [list @c@ $cond @b@ $body] {
if {![catch {expr {@c@}} res] && $res} {
return [eval {@b@}]
}
}][info body unknown]
}
know {[regexp {^([a-z]+)\.([a-z]+)$} [lindex $args 0] -> from to]} {
set res {}
while {$from<=$to} {lappend res $from; incr from}
set res
}
# % puts [1..5]
# 1 2 3 4 5
proc know{cond body}{
proc unknown{args}[字符串映射[list@c@$cond@b@$body]{
如果{![catch{expr{@c@}}res]&&&$res}{
返回[eval{@b@}]
}
}][信息正文未知]
}
知道{[regexp{^([a-z]+)\([a-z]+)$}[lindex$args 0]->from to]}{
集合res{}
虽然{$from可以对特定操作执行,但不是所有操作,并且存在一些语法限制。例如:
know {[regexp {^(.*)\.length$} [lindex $args 0] -> value]} {
string length $value
}
puts [abc.length]
# ---> 3
set thevar "abc def"
puts [$thevar.length]
# ---> 7
puts ["abc def".length]
# ---> extra characters after close-quote
也就是说,值必须仍然是语法上有效的Tcl;最后一个示例不是。如果您有基本情况的处理程序,则可以通过在处理程序中使用[$value]
而不是普通的$value
来链接know
处理程序
know {[regexp {^(.*)\.length$} [lindex $args 0] -> value]} {
string length [$value]
}
know {[regexp {^(.*)\.repeat\((\d+)\)$} [lindex $args 0] -> value count]} {
string repeat [$value] $count
}
# Base case for simple words
know {[regexp {^'(.*)'$} [lindex $args 0] -> value]} {
set value
}
puts ['abc\ def'.repeat(5).length]
# ---> 35
归根结底,虽然你可以做各种类似的事情,但这不是Tcl的工作方式。它会很慢(未知的调用机制不是一个优化的路径),你会遇到限制。最好学会用正常的方式做事情:
puts [string length [string repeat "abc def" 5]]
简言之,如果您想要Ruby,请使用Ruby。如果是嵌套导致代码显得相当混乱,那么使用控制结构类型命令将类似管道的序列重写到相应的嵌套命令中会很有帮助。我经常使用这种技术。请访问Tcl wiki获取示例。