Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2042750
  • 博文数量: 519
  • 博客积分: 10070
  • 博客等级: 上将
  • 技术积分: 3985
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-29 14:05
个人简介

只问耕耘

文章分类

全部博文(519)

文章存档

2016年(1)

2013年(5)

2011年(46)

2010年(220)

2009年(51)

2008年(39)

2007年(141)

2006年(16)

我的朋友

分类: Python/Ruby

2010-05-18 16:51:47

基本概念
  Tcl (最早称为“工具命令语言”"Tool Command Language", 但是目前已经不是这个含义,不过我们仍然称呼它为TCL)是一种 脚本语言。 由John Ousterhout创建。 TCL很好学,功能很强大。TCL经常被用于 快速原型开发,脚本编程, GUI和测试等方面。TCL念作“踢叩” "tickle". Tcl的特性包括:
  * 任何东西都是一条命令,包括语法结构(for, if等)。
  * 任何事物都可以重新定义和重载。
  * 所有的数据类型都可以看作字符串。
  * 语法规则相当简单
  * 提供事件驱动给Socket和文件。基于时间或者用户定义的事件也可以。
  * 动态的域定义。
  * 很容易用C, C++,或者Java扩展。
  * 解释语言,代码能够动态的改变。
  * 完全的Unicode支持。
  * 平台无关。Win32, UNIX, Mac 上都可以跑。
  * 和Windows的GUI紧密集成。 Tk
  * 代码紧凑,易于维护。
  TCL本身不提供面向对象的支持。但是语言本身很容易扩展到支持面向对象。许多C语言扩展都提供面向对象能力,包括XOTcl, Incr Tcl 等。另外SNIT扩展本身就是用TCL写的。
  使用最广泛的TCL扩展是TK。 TK提供了各种OS平台下的图形用户界面GUI。连强大的Python语言都不单独提供自己的GUI,而是提供接口适配到TK上。另一个流行的扩展包是Expect. Expect提供了通过终端自动执行命令的能力,例如(passwd, ftp, telnet等命令驱动的外壳).
[编辑本段]具体例子
  下面是TCL程序的例子:
  #!/bin/sh
  # next line restarts using tclsh in path \
  exec tclsh ${1+"$@"}
  # echo server that can handle multiple
  # simultaneous connections.
  proc newConnection { sock addr port } {
  # client connections will be handled in
  # line-buffered, non-blocking mode
  fconfigure $sock -blocking no -buffering line
  # call handleData when socket is readable
  fileevent $sock readable [ list handleData $sock ]
  }
  proc handleData {
  puts $sock [ gets $sock ]
  if { [ eof $sock ] } {
  close $sock
  }
  }
  # handle all connections to port given
  # as argument when server was invoked
  # by calling newConnection
  set port [ lindex $argv 0 ]
  socket -server newConnection $port
  # enter the event loop by waiting
  # on a dummy variable that is otherwise
  # unused.
  vwait forever
  另外一个TK的例子 (来自 A simple A/D clock) 它使用了定时器时间,3行就显示了一个时钟。
  proc every {ms body} {eval $body; after $ms [info level 0]}
  pack [label .clock -textvar time]
  every 1000 {set ::time [clock format [clock sec] -format %H:%M:%S]} ;# RS
  解释:第一行定义了过程every, 每隔ms毫秒,就重新执行body代码。第二行创建了标签起内容由time变量决定。第3行中设置定时器,time变量从当前时间中每秒更新一次。
  Tcl被广泛的用做script语言,大多数情况下,Tcl和Tk(“Tool Kit”)库同时使用,Tk是一系列令Tcl易于编写图形用户接口的命令和过程
  Tcl的一个重要特性是它的扩展性。如果一个程序需要使用某些标准Tcl没有提供的功能,可以使用c语言创造一些新的Tcl命令,并很容易的融合进去。正是由于Tcl易于扩展,很多人为它编写了扩展包,并在网上共享。
  Tcl和其他编程语言例如c不同,它是一种解释语言而非编译语言。Tcl程序由一系列Tcl命令组成,在运行时由Tcl解释器解释运行。解释运行的一个优点是它可以自己为自己生成Tcl script。
[编辑本段]变量和变量交换
  不像c,Tcl的变量在使用前不需要声明。Tcl的变量在它首次被赋值时产生,使用set命令。变量可以用unset命令删除,虽然并不强制需要这样做。
  变量的值通过$符号访问,也叫变量交换。
  Tcl是一个典型的”弱类型定义”语言,这意味者任何类型可以存储在任何变量中。例如,同一个变量可以存储数字,日期,字符串甚至另一段Tcl script.
  Example 1.1:
  set foo "john"
  puts "Hi my name is $foo"
  Output: Hi my name is john
  Example 1.2:
  set month 2
  set day 3
  set year 97
  set date "$month:$day:$year"
  puts $date
  Output: 2:3:97
  Example 1.3:
  set foo "puts hi"
  eval $foo
  Output: hi
  在这个例子里,变量foo存储了另外一段Tcl script.
  表达式
  包括数学表达式,关系表达式,通常用 expr命令。
  Example 2.1:
  expr 0 == 1
  Output: 0
  Example 2.2:
  expr 1 == 1
  Output: 1
  两数比较,true则输出1,false输出0
  Example 2.3:
  expr 4 + 5
  Output: 9
  Example 2.4:
  expr sin(2)
  Output: 0.909297
  命令传递
  以运算结果替代Tcl命令中的部分
  Example 3.1:
  puts "I am [expr 10 * 2] years old, and my I.Q. is [expr 100 - 25]"
  Output: I am 20 years old, and my I.Q. is 75
  方括号是命令传递的标志
  Example 3.2:
  set my_height 6.0
  puts "If I was 2 inches taller, I would be [expr $my_height + (2.0 / 12.0)] feet tall"
  Output: If I was 2 inches taller, I would be 6.16667 feet tall
  命令流控制
  Tcl有判断流转(if-else; switch)和循环控制(while; for; foreach)
  Example 4.1:
  set my_planet "earth"
  if {$my_planet == "earth"} {
  puts "I feel right at home."
  } elseif {$my_planet == "venus"} {
  puts "This is not my home."
  } else {
  puts "I am neither from Earth, nor from Venus."
  }
  set temp 95
  if {$temp < 80} {
  puts "It's a little chilly."
  } else {
  puts "Warm enough for me."
  }
  Output:
  I feel right at home.
  Warm enough for me.
  Example 4.2:
  set num_legs 4
  switch $num_legs {
  2 {puts "It could be a human."}
  4 {puts "It could be a cow."}
  6 {puts "It could be an ant."}
  8 {puts "It could be a spider."}
  default {puts "It could be anything."}
  }
  Output:
  It could be a cow.
  Example 4.3:
  for {set i 0} {$i < 10} {incr i 1} {
  puts "In the for loop, and i == $i"
  }
  Output:
  In the for loop, and i == 0
  In the for loop, and i == 1
  In the for loop, and i == 2
  In the for loop, and i == 3
  In the for loop, and i == 4
  In the for loop, and i == 5
  In the for loop, and i == 6
  In the for loop, and i == 7
  In the for loop, and i == 8
  In the for loop, and i == 9
  Example 4.4:
  set i 0
  while {$i < 10} {
  puts "In the while loop, and i == $i"
  incr i 1
  }
  Output:
  In the while loop, and i == 0
  In the while loop, and i == 1
  In the while loop, and i == 2
  In the while loop, and i == 3
  In the while loop, and i == 4
  In the while loop, and i == 5
  In the while loop, and i == 6
  In the while loop, and i == 7
  In the while loop, and i == 8
  In the while loop, and i == 9
  Example 4.5:
  foreach vowel {a e i o u} {
  puts "$vowel is a vowel"
  }
  Output:
  a is a vowel
  e is a vowel
  i is a vowel
  o is a vowel
  u is a vowel
  Procedures
[编辑本段]参数定义方法
  Tcl的Procedures 和c的函数差不多. 它们有参数,它们返回值。基本定义方法是:
  proc name argList body
  当一个procedure被定义,它就被看做是一个命令,如同Tcl的自带命令一样,通过名字来呼叫,名字后面跟上参数。
  缺省的,procedure的返回值是它的最后一个命令结果。但也可以通过return命令来返回其他值。Return值可以在procedure的任何地方,一旦执行,procedure就此返回。
  Example 5.1:
  proc sum_proc {a b} {
  return [expr $a + $b]
  }
  proc magnitude {num} {
  if {$num > 0} {
  return $num
  }
  set num [expr $num * (-1)]
  return $num
  }
  set num1 12
  set num2 14
  set sum [sum_proc $num1 $num2]
  puts "The sum is $sum"
  puts "The magnitude of 3 is [magnitude 3]"
  puts "The magnitude of -2 is [magnitude -2]"
  Output:
  The sum is 26
  The magnitude of 3 is 3
  The magnitude of -2 is 2
  在procedure中可以通过set创造变量,但是变量只在procedure中有效,而且一旦procedure返回,这些变量就不可访问。如果procedure需要访问主程序中的变量,就需要使用global关键字。
  Example 5.2:
  proc dumb_proc {} {
  set myvar 4
  puts "The value of the local variable is $myvar"
  global myglobalvar
  puts "The value of the global variable is $myglobalvar"
  }
  set myglobalvar 79
  dumb_proc
  Output:
  The value of the local variable is 4
  The value of the global variable is 79
[编辑本段]Lists
  Lists就好像是Tcl中的一种特殊的数组。它吧一堆东西放成一个集合,然后就像操作一个整体一样的操作它。
  Example 6.1:
  set simple_list "John Joe Mary Susan"
  puts [lindex $simple_list 0]
  puts [lindex $simple_list 2]
  Output:
  John
  Mary
  注意list的index是从0开始的
  Example 6.2:
  set simple_list2 "Mike Sam Heather Jennifer"
  set compound_list [list $simple_list $simple_list2]
  puts $compound_list
  puts [llength $compound_list]
  Output:
  {John Joe Mary Susan} {Mike Sam Heather Jennifer}
  2
  Example 6.3:
  set mylist "Mercury Venus Mars"
  puts $mylist
  set mylist [linsert $mylist 2 Earth]
  puts $mylist
  lappend mylist Jupiter
  puts $mylist
  Output:
  Mercury Venus Mars
  Mercury Venus Earth Mars
  Mercury Venus Earth Mars Jupiter
  Arrays
  Tcl数组在使用前无须定义,大小也不用指定。
  Example 7.1:
  set myarray(0) "Zero"
  set myarray(1) "One"
  set myarray(2) "Two"
  for {set i 0} {$i < 3} {incr i 1} {
  puts $myarray($i)
  }
  Output:
  Zero
  One
  Two
  Example 7.2:
  set person_info(name) "Fred Smith"
  set person_info(age) "25"
  set person_info(occupation) "Plumber"
  foreach thing {name age occupation} {
  puts "$thing == $person_info($thing)"
  }
  Output:
  name == Fred Smith
  age == 25
  occupation == Plumber
  这个例子指出数组的index不需要是数字,其他类型的数据也可以。
  Example 7.3:
  set person_info(name) "Fred Smith"
  set person_info(age) "25"
  set person_info(occupation) "Plumber"
  foreach thing [array names person_info] {
  puts "$thing == $person_info($thing)"
  }
  Output:
  occupation == Plumber
  age == 25
  name == Fred Smith
  Strings
  字符串是Tcl中最常用的类型,string有很多使用参数,可以参照Tcl手册。使用方法:
  string option arg arg ...
  Example 8.1:
  set str "This is a string"
  puts "The string is: $str"
  puts "The length of the string is: [string length $str]"
  puts "The character at index 3 is: [string index $str 3]"
  puts "The characters from index 4 through 8 are: [string range $str 4 8]"
  puts "The index of the first occurrence of letter \"i\" is: [string first i $str]"
  Output:
  The string is: This is a string
  The length of the string is: 16
  The character at index 3 is: s
  The characters from index 4 through 8 are: is a
  The index of the first occurrence of letter "i" is: 2
  Input/Output
  Tcl的绝大多数输入/输出是通过puts和gets做到的。Puts命令显示在console上,gets命令从console输入上取得数据,并存储在某个变量中。
[编辑本段]gets channelId varName
  channelID可以理解为c的文件句柄,varName如果定义,输入值就赋给它,gets返回读入的字节数,否则gets直接返回输入值。
  Example 9.1:
  puts -nonewline "Enter your name: "
  set bytesread [gets stdin name]
  puts "Your name is $name, and it is $bytesread bytes long"
  Output: (note that user input is shown in italics)
  Enter your name: Shyam
  Your name is Shyam, and it is 5 bytes long
  Example 9.2:
  set f [open "/tmp/myfile" "w"]
  puts $f "We live in Texas. It's already 110 degrees out here."
  puts $f "456"
  close $f
  Output: (none)
  Open打开了一个 "/tmp/myfile" 作为channel. 用法是:
  open name access
  access参数指出打开文件的方式,”w”是读写。这时可以用puts $f把内容写入文件
  Example 9.3:
  set f [open "/tmp/myfile" "r"]
  set line1 [gets $f]
  set len_line2 [gets $f line2]
  close $f
  puts "line 1: $line1"
  puts "line 2: $line2"
  puts "Length of line 2: $len_line2"
  Output:
  line 1: We live in Texas. It's already 110 degrees out here.
  line 2: 456
  Length of line 2: 3
  这个例子假设已知文件只有两行,如果不是,则需要使用循环,用eof来找到文件尾。
  eval
  eval命令会把它的参数直接送往解释器。
  Example 10.1:
  set foo "set a 22"
  eval $foo
  puts $a
  Output:
  22
  单纯的执行$foo不会成功。
  catch
  Example 10.2:
  set retval [catch {set f [open "nosuchfile" "r"]}]
  if {$retval == 1} {
  puts "An error occured"
  }
  Output: (this output occurs if there is no file named "nosuchfile" in the current directory).
  An error occured
  Catch 参数记录一个script的执行情况,如果返回值为1,则执行出错。用来进行错误处理。
阅读(1734) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~