我一直在使用 TCL/TK,最近开始在我的自动化应用程序中使用 TCL/TK,我渴望知识。
继续一长串隐藏特征问题,我想知道 TCL/TK 的任何隐藏或方便的功能,或者任何简单的方法来实现一些大操作
我最喜欢的“隐藏或方便的特性”是引用在 Tcl 中的工作方式。我喜欢用“引用是一种工具,而不是规则”这句话。我也想说“当你需要花括号时,你只需要花括号”
虽然大多数语言都有规则规定必须为某些事情使用块分隔符(例如,在 C 中您必须使用 {} 来指定块),但 Tcl 并没有那么严格。
使用 Tcl,您可以选择任何给您所需效果的引用字符。当然有最佳实践,但最后你要选择最能帮助你完成工作的引用字符。
这意味着,例如,您可以通过多种方式定义过程,包括:
proc foo {args} {
.... body here ....
}
proc foo "args" "
.... body here ....
"
proc foo args [some code that returns the body]
... 等等。条件语句、循环和其他所有内容也是如此。(对于外行来说,花括号大致相当于shell单引号,双引号相当于shell双引号,方括号相当于shell反引号。)。
现在,很多人看到这个并说WTF?但它确实给了程序员很大的权力。我们经常在 comp.lang.tcl 中遇到类似“如果我执行 'this {and $that}',我如何让 $that 被扩展?”这样的问题。答案遵循老笑话“病人:医生,当我做这个医生时很痛:不要那样做”。也就是说,如果您不喜欢使用一组定界符获得的行为,请选择其他定界符。仅仅因为 if 语句通常用花括号构造并不意味着它必须用花括号构造。
这是我最喜欢的 Tcl 的“隐藏”特性。它不是隐藏的——它就在非常完整而简洁的 Tcl(n) 手册页上,但在您完全了解 Tcl 的工作原理之前,其后果并不明确。
当 Sun 的营销人员宣称 Tcl 已“企业就绪”时,开发人员添加了以下功能:
$ tclsh
% clock format [clock seconds] -format %Q
Stardate 63473.2
另一个不明显的特性是无法识别的命令会落入一个称为“未知”的处理程序,您可以重新定义它。例如。将未知命令视为表达式来评估:
$ tclsh
% 2+2
invalid command name "2+2"
% proc unknown args {uplevel 1 [linsert $args 0 expr]}
% 2+2
4
更多示例可以在激进语言修改的 wiki 页面上找到
Tcl 的 [trace] 命令允许您拦截对任何变量的读取和写入。这允许您在任何变量上实现观察者,并向任何变量添加任意复杂性的自动范围检查(就像您通过 setter/getter 访问变量一样)。您还可以使用此技术创建自动递增变量。
proc varlimit_re {re var key op} {
upvar $var v
if { [regexp -- $re $v] <= 0 } {
error "$var out of range"
}
}
trace add variable ::myvar {write} [list varlimit_re {^[A-H]\d{3}-[0-9a-f]+$}]`
如果您尝试将 'myvar' 设置为与正则表达式不匹配的任何内容,您将收到运行时错误。
一个没有隐藏但对来自其他语言的人来说并不明显的便利功能是,您可以定义自己的控制结构(如果您想危险地生活,甚至可以重新定义现有的控制结构)。Tcl Wiki上有示例
Tcl 的所有“关键字”都是常规的 Tcl 命令,包括 [for]、[foreach]、[while] 等控制结构。这意味着您可以通过在纯 Tcl 代码中编写新的控制结构来扩展语言。
例如,try/on/trap结构已在 Tcl 8.6a 中仅使用 Tcl 代码实现。类似地,tcllib 包含 control::do,一个 do/while 控制结构。
很多这些都是通过 [upvar] 和 [uplevel] 命令实现的,它们允许您访问变量或在不同的堆栈帧中执行代码。
恕我直言,Tcl 最大的隐藏特性是它的C API。 使用它,包装核心 C 程序或子系统并在 Tcl 中编写 GUI 或其他功能非常容易。虽然这个特性不是 Tcl 独有的,但 Tcl 的设计初衷就是为了做到这一点,而且 C API 特别易于使用。
第二个最大的隐藏特性是packer,它是所有几何管理器的祖父。这样一来,GUI 就可以拥有相当大的窗口,而代码量却很少。需要注意的是,Tcl/Tk 至少在 .net 出现之前 10 年就有几何管理。
Tcl 的第三大特点是能够通过 C API 或使用 Tcl 中定义的命令来扩展语言。不完全是 LISP 宏,但非常灵活。 Expect是一个很好的应用程序示例,它围绕扩展 basse Tcl 语言以制作特定领域的脚本语言而构建。
编辑:好吧,烦死我了,Xt确实有一个几何管理器,尽管我同意 Nat 的观点,因为它比 pack 更痛苦;-}
Tcl 是一种如此简单、开放的语言,几乎没有隐藏的特性。这一切都暴露给程序员扩展和适应。
[array names]
是新手询问如何迭代数组的第一个问题foreach {key1 key2} {$list1 $list2} {...}
- 即使列表大小不同rename
命令可以重命名任何函数/过程我认为时间命令很棒。它并没有完全隐藏,但这并不能阻止人们偶尔在 comp.lang.tcl 中询问“哪个函数更快”。
任何时候您都想知道“这需要多长时间?” 或“哪种方法更快?” 您只需通过“时间”命令调用它。没有创建对象,没有数学,没有开销,非常简单。其他语言也有类似的特性,虽然有些不太优雅。
有据可查的 C API 还允许在 Perl 中轻松集成。我使用 Tcl/Tk 的经验可以追溯到 1995 年,但在 2000 年左右,我发现了 Perl/Tk,并且再也没有回头。
最近,Tcl 和 Tkx Perl 包为我们提供了具有现代感的 GUI。考虑到它们允许跨语言边界做什么,上述两个模块虽然不是微不足道的,但涉及的代码相对较少。这可以直接归功于出色的 API(显然还有 Perl 的强大功能)。