TCL/TK的隐藏特性

TCL/TK的隐藏特性,tcl,tk,Tcl,Tk,我一直在使用TCL/TK,最近开始在我的自动化应用程序中使用TCL/TK,我渴望获得知识 为了继续讨论一长串隐藏的功能问题,我想知道TCL/TK的任何隐藏的或方便的功能,或者实现一些大型操作的任何简单方法当Sun的一位营销人员宣布TCL已“做好企业准备”时,开发人员添加了以下功能: $ tclsh % clock format [clock seconds] -format %Q Stardate 63473.2 一个不隐藏但对来自其他语言的人来说并不明显的便捷功能是,您可以定义自己的控制结构

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


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

当Sun的一位营销人员宣布TCL已“做好企业准备”时,开发人员添加了以下功能:

$ tclsh
% clock format [clock seconds] -format %Q
Stardate 63473.2

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

上有一些例子,我最喜欢的“隐藏或方便功能”是如何在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的工作原理之前,其后果并不清楚

另一个不明显的特性是,无法识别的命令会落入一个名为“unknown”的处理程序,您可以重新定义该处理程序。例如,将未知命令视为表达式进行计算:

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

更多示例可以在

im的wiki页面上找到,而Tcl最大的隐藏功能就是使用它,在Tcl中包装核心C程序或子系统并编写GUI或其他功能非常容易。虽然这个特性不是Tcl独有的,但Tcl的设计初衷就是要做到这一点,而C API尤其易于使用

第二个最大的隐藏特性是几何体管理器,它是所有几何体管理器中的老爹。这样一来,GUI就可以拥有相当大的窗口,而代码量却少得惊人。值得注意的是,Tcl/Tk在.net问世前至少10年就有了几何体管理

Tcl的第三大特性是能够通过C API或使用Tcl中定义的命令来扩展该语言。不是很LISP宏,但还是很灵活。是一个非常好的应用程序示例,该应用程序围绕扩展basse Tcl语言来生成特定于域的脚本语言而构建


编辑:好吧,麻烦我,Xt,尽管我同意Nat的观点,因为它比pack更痛苦;-}

Tcl是一种简单、开放的语言,几乎没有隐藏的功能。程序员可以对其进行扩展和调整。

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

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


通过[upvar]和[uplevel]命令可以实现这一点,它们允许您在不同的堆栈框架中访问变量或执行代码

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]+$}]`
proc varlimit\u re{re var key op}{
upvar$var v

如果{[regexp--$re$v]文档丰富的C API也允许在Perl中轻松集成。我使用Tcl/Tk的经验可以追溯到1995年,但在2000年左右,我发现了Perl/Tk,从此不再回头

最近,Tcl和Tkx Perl软件包为我们提供了外观现代的GUI。上述两个模块虽然不平凡,但涉及的代码相对较少,考虑到它们允许人们跨越语言边界进行操作。这可以直接归因于优秀的API(显然还有Perl的强大功能)

  • [array names]
    是新手关于如何迭代数组的首要问题之一
  • 此外,您可以
    foreach{key1 key2}{$list1$list2}{…}
    ——即使列表大小不同
  • 您不应该在切换案例之间使用注释(这不是一个很酷的特性,但大多数开发人员不理解这个问题)
  • rename
    命令可以重命名任何函数/proc
  • 我认为这个命令很棒。它并不是完全隐藏的,但这并不能阻止人们偶尔在comp.lang.tcl中问“哪个函数更快”

    随时都可以