Tcl

Table of Contents

1. Tcl 简介

Tcl (Tool Command Language) was created in the spring of 1988 by John Ousterhout.

1.1. 程序结构

Tcl 程序由一个或多个“Command”组成,“Command”之间用“换行符”或者“分号”进行分隔。

在 Tcl 中,“Command”是个很广的概念,其它语言中的“语句”、“控制结构”等在 Tcl 中都被称为“Command”,它的形式如下:

commandName argument1 argument2 ... argumentN

# 开始的行是注释,如果 # 出现在行尾,则前面的命令结束时需要增加分号,如:

command1 argument1 argument2 ... argumentN
command2 argument1 argument2 ... argumentN;    # 由于有注释,在 command2 结束后要加上分号

每个命令都有返回结果,如果某个命令没有有意义的返回结果,那么它返回空字符串。

Tcl 的命令列表可参考:Tcl Commands

1.2. Hello World

Tcl 版的“Hello World”如下:

puts "Hello, World!"

puts 命令默认将把其后面的字符串外加个换行符输出到标准输出中。

2. 变量和表达式

Tcl 中变量不需要提前声明,变量也没有类型。

Tcl 使用 set 为变量设置值(不使用等号进行赋值),变量名前加个 $ 符号就可以把变量值替换到当前的位置:

set x 32
puts $x;                   # 相当于 puts 32

expr 可以执行一个表达式,如:

expr 1 + 2;                # expr 的结果为 3

set x [expr 1 + 2];        # 把 expr 的结果保存到 x 中
puts $x;                   # 输出 3

语法 [] 后文将介绍。

3. 命令替换( []

[] 中的内容是“子命令”,Tcl 将执行它,并把子命令的结果放到当前位置,如:

set a 44
set b [expr $a*4];         # b 为 176

4. 引号和大括号

双引号可以让命令的参数包含空格:

set x 24
set y 18
set z "$x + $y is [expr $x + $y]";         # 变量 z 的内容为 24 + 18 is 42

大括号 {} 中的内容不会被替换(变量不会被替换,命令也不会被替换),如:

set z {$x + $y is [expr $x + $y]};         # 变量 z 的内容为 $x + $y is [expr $x + $y]

5. 控制结构

Tcl 支持 if, for, foreach, while 等等控制结构。

Tcl 中可以使用 proc 创建一个新“Command”:

proc power {base p} {
    set result 1
    while {$p > 0} {
        set result [expr $result * $base]
        set p [expr $p - 1]
    }
    return $result
}

puts [power 2 6];               # 输出 64

6. 命令的来源

前面说过,Tcl 中几乎所有东西都是命令,那命令有哪些来源呢?有三个来源:
1、解释器中内置的命令(如前面介绍的 set, puts 等等);
2、由 Tcl extension mechanism 生成的命令(Tcl 提供了 API,可以由 C/C++ 实现命令);
3、由命令 proc 生成的命令。

7. 实例

7.1. dos2unix

下面是 Tcl 实现的 doc2unix 命令:

#!/usr/local/bin/tclsh

# Dos2Unix
#	Convert a file to Unix-style line endings
#	If the file is a directory, then recursively
#	convert all the files in the directory and below.
#
# Arguments
#	f	The name of a file or directory.
#
# Side Effects:
#	Rewrites the file to have LF line-endings

proc Dos2Unix {f} {
    puts $f
    if {[file isdirectory $f]} {
	foreach g [glob [file join $f *]] {
	    Dos2Unix $g
	}
    } else {
	set in [open $f]
	set out [open $f.new w]
	fconfigure $out -translation lf
	puts -nonewline $out [read $in]
	close $out
	close $in
	file rename -force $f.new $f
    }
}

# Process each command-line argument

foreach f $argv {
    Dos2Unix $f
}

代码摘自:https://www.tcl-lang.org/about/dos2unix.html

8. 参考

Author: cig01

Created: <2018-11-24 Sat>

Last updated: <2020-01-05 Sun>

Creator: Emacs 27.1 (Org mode 9.4)