18

我一直在使用 TCL/TK,最近开始在我的自动化应用程序中使用 TCL/TK,我渴望知识。

继续一长串隐藏特征问题,我想知道 TCL/TK 的任何隐藏或方便的功能,或者任何简单的方法来实现一些大操作

4

11 回答 11

18

我最喜欢的“隐藏或方便的特性”是引用在 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 的工作原理之前,其后果并不明确。

于 2009-06-22T13:59:56.173 回答
14

当 Sun 的营销人员宣称 Tcl 已“企业就绪”时,开发人员添加了以下功能:

$ tclsh
% clock format [clock seconds] -format %Q
Stardate 63473.2
于 2009-06-22T11:20:36.773 回答
12

另一个不明显的特性是无法识别的命令会落入一个称为“未知”的处理程序,您可以重新定义它。例如。将未知命令视为表达式来评估:

$ tclsh
% 2+2
invalid command name "2+2"
% proc unknown args {uplevel 1 [linsert $args 0 expr]} 
% 2+2
4

更多示例可以在激进语言修改的 wiki 页面上找到

于 2009-06-22T16:33:30.180 回答
12

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' 设置为与正则表达式不匹配的任何内容,您将收到运行时错误。

于 2009-06-23T10:31:22.140 回答
8

一个没有隐藏但对来自其他语言的人来说并不明显的便利功能是,您可以定义自己的控制结构(如果您想危险地生活,甚至可以重新定义现有的控制结构)。Tcl Wiki上有示例

于 2009-06-22T13:17:12.810 回答
8

Tcl 的所有“关键字”都是常规的 Tcl 命令,包括 [for]、[foreach]、[while] 等控制结构。这意味着您可以通过在纯 Tcl 代码中编写新的控制结构来扩展语言。

例如,try/on/trap结构已在 Tcl 8.6a 中仅使用 Tcl 代码实现。类似地,tcllib 包含 control::do,一个 do/while 控制结构。

很多这些都是通过 [upvar] 和 [uplevel] 命令实现的,它们允许您访问变量或在不同的堆栈帧中执行代码。

于 2009-06-23T09:27:30.100 回答
7

恕我直言,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 更痛苦;-}

于 2009-06-22T16:34:44.987 回答
7

Tcl 是一种如此简单、开放的语言,几乎没有隐藏的特性。这一切都暴露给程序员扩展和适应。

于 2009-06-22T17:00:45.473 回答
6
  1. [array names]是新手询问如何迭代数组的第一个问题
  2. 此外,您可以foreach {key1 key2} {$list1 $list2} {...}- 即使列表大小不同
  3. 你不应该在 switch case 之间使用注释(这不是一个很酷的功能,但大多数开发人员不理解的问题
  4. rename命令可以重命名任何函数/过程
于 2009-07-28T21:08:58.540 回答
6

我认为时间命令很棒。它并没有完全隐藏,但这并不能阻止人们偶尔在 comp.lang.tcl 中询问“哪个函数更快”。

任何时候您都想知道“这需要多长时间?” 或“哪种方法更快?” 您只需通过“时间”命令调用它。没有创建对象,没有数学,没有开销,非常简单。其他语言也有类似的特性,虽然有些不太优雅。

于 2009-08-25T17:34:37.027 回答
2

有据可查的 C API 还允许在 Perl 中轻松集成。我使用 Tcl/Tk 的经验可以追溯到 1995 年,但在 2000 年左右,我发现了 Perl/Tk,并且再也没有回头。

最近,Tcl 和 Tkx Perl 包为我们提供了具有现代感的 GUI。考虑到它们允许跨语言边界做什么,上述两个模块虽然不是微不足道的,但涉及的代码相对较少。这可以直接归功于出色的 API(显然还有 Perl 的强大功能)。

于 2009-06-26T12:37:29.027 回答