Tcl学习笔记

2004/12/28
Regular expression to parse the DISPLAY environment variable.

set env(DISPLAY) corvina:0.1

regexp {([^:]*):} $env(DISPLAY) match host

=> 1

set match

=> corvina:

set host

=> corvina

The example uses regexp to pick the hostname out of the DISPLAY environment

variable, which has the form:

hostname:display

The pattern involves a complementary set, [^:], to match anything except

a colon. It uses repetition, *, to repeat that zero or more times. Then, it groups

that part into a subexpression with parentheses. The literal colon ensures that

the DISPLAY value matches the format we expect. The part of the string that

matches the pattern will be stored into the match variable. The part that we

really want is what matches the subpattern, and that will be stored into host.

The whole pattern has been grouped with braces to avoid the special meaning of

the square brackets to the Tcl interpreter. Without braces it would be:

regexp (/[^:]*): $env(DISPLAY) match host

This is quite a powerful statement, and it is efficient. If we only had the

string command to work with, we would have had to resort to the following,

which takes roughly twice as long to interpret.

set i [string first : $env(DISPLAY)]

if {$i >= 0} {

set host [string range $env(DISPLAY) 0 [expr $i-1]]

}

Multiple subpatterns are allowed. We can improve our pattern so that it

28 Strings and Pattern Matching Chap.2

Created: December 15, 1994 —Strings.fm3—Copyright Prentice Hall—DRAFT: 1/11/95

extracts the screen part of the DISPLAY as well as the host:

regexp {([^:]*):(.+)} $env(DISPLAY) match host screen

 

 

FAQ: exec

%set paddress [ypmatch $host hosts];puts $paddress

200.61.250.220  gsncd20

 

% set paddress [exec ypmatch $host hosts];puts $paddress

200.61.250.220  gsncd20 _

 

第一种情况paddress为空

 

FAQ: set

set i a


申明了一个名称为i的变量

set $i 1

申明了一个名称为$i”的变量,这个怪物能用[expr $$i]题出来,
puts ${$i}未遂,说变量$i未定义。
puts $$i得到$a
还不知道怎么办,而是如果不先声明i,则$i不会声明成功


同样的事情在puts/getscommand


2005/1/4:终于明白原因了set $i 1其实被解析为set a 1,是对变量a赋了值,另外一种方式为set [set i]

 

FAQ: env

$env(DISPLAY)

在函数中用的时候,一定要记得申明其为全局变量:

global env


 
Variables defined by tclsh.(can also use the info vars command to find out what is defined.)

argc The number of command line arguments
argv A list of the command line arguments
argv0 The name of the script being executed. If being used interactively,
argv0 is the name of the shell program.
env An array of the environment variables. See page 38.
tcl_interactive True (one) if the tclsh is prompting for commands.
tcl_prompt1 If defined, this is a command that outputs the prompt. .
tcl_prompt2 If defined, this is a command that outputs the prompt if the
current command is not yet complete.
auto_path The search path for script library directories. See page 90.
auto_index A map from command name to a Tcl command that defines it.
auto_noload If set, the library facility is disabled.
auto_noexec If set, the auto execute facility is disabled.
geometry (wish only). The value of the -geometry argument.

 

FAQ: How to include files

在代码里用source “xxxxx.tcl”


2004/12/29
destructor body
Declares the body used for the destructor, which is automatically invoked when an object
is deleted. If the destructor is successful, the object data is destroyed and the object name
is removed as a command from the interpreter. If destruction fails, an error message is
returned and the object remains.
When an object is destroyed, all destructors in its class hierarchy are invoked in order
from most- to least-specific. This is the order that the classes are reported by the "info
heritage" command, and it is exactly the opposite of the default constructor order.

2005/01/04
set i 1 ; while $i<=10 {incr i}
The loop will run indefinitely. The bug is that the Tcl interpreter will substitute
for $i before while is called, so while gets a constant expression 1<=10 that
will always be true. You can avoid these kinds of errors by adopting a consistent
coding style that always groups expressions and command bodies with curly
braces.

string range abcd 1 end
=> bcd
不用什么string range abcd 1 [string length xxxx]

说说format
A position specifier is i$, which means take the value from argument i as
opposed to the normally corresponding argument. The position counts from 1. If
you group the format specification with double-quotes, you will need to quote the
$ with a backslash.
set lang 2
format “%${lang}/$s” one un uno
=> un
The position is useful for picking a string from a set, such as this simple
language-specific example. The position is also useful if the same value is
repeated in the formatted string. If a position is specified for one format keyword,
it must be used for all of them.
注意%%n$不能在一条语句中混用。

You can compute a field width and pass it to format as one of the arguments
by using * as the field width specifier. In this case the next argument is used as
the field width instead of the value, and the argument after that is the value that
gets formatted.
set maxl 8
format “%-*s = %s” $maxl Key Value

DIFFERENCES FROM ANSI SPRINTF
The behavior of the format command is the same as the ANSI C sprintf procedure except for the following
differences:
[1] %p and %n specifiers are not currently supported.
[2] For %c conversions the argument must be a decimal string, which will then be converted to the corresponding character value.
[3] The l modifier is ignored; integer values are always converted as if there were no modifier present
and real values are always converted as if the l modifier were present (i.e. type double is used for
the internal representation). If the h modifier is specified then integer values are truncated to short
before conversion.


string match {[ab]*} cello
=> 0
Be careful! Square brackets are also special to the Tcl interpreter, so you’ll
need to wrap the pattern up in curly braces to prevent it from being interpreted
as a nested command.
Another approach is to put the pattern into a variable:
set pat {[ab]*x}
string match $pat box
=> 1

match one of a set of characters([ abc]):The string match function does not support alternation in a pattern, such as the
{a,b,c} syntax of the C-shell. The glob command, however, does support this form.


Using info to determine if a variable exists.
if ![info exists foobar] {
set foobar 0
} else {
incr foobar
}

 

2004/01/05

tcsh下敲@,出来好多奇怪的DD:)

 

set ::SCRIPT_DIR [file dirname [info script]]

set here [pwd] ; cd $::SCRIPT_DIR ; set ::SCRIPT_DIR [pwd] ; cd $here

 

set v(a) a

set v(a,a) a

!一个变量既可以是1维数组,也可以是N维数组。

 

set    WELCOME [read [set fh [open $_welcome r]]][close $fh]

 

run once cache proc

proc admin_possible {} {

    set ap [check_admin_possible]

    proc admin_possible {} [list return $ap]

    return $ap

}

 

proc plugin_mime_possible {} {

    # Do we have access to the mime database ?

    set testkey {HKEY_CLASSES_ROOT/MIME/Database/Content Type/application/x-activestate-installer}

    if {[catch {registry set $testkey}]} {return 0}

    catch {registry delete $testkey}

    return 1

}

 

 

 

2005/1/15

multi-switch(use ‘-’)

    switch $::tcl_platform(os) {

      FreeBSD - Linux - OSF1 - SunOS {

          # Bugfix: If the path in an entry is too long SunOS splits

          # the entry into two lines, one containing the path, the

          # other containing the remainder of the information. This

          # means that every in the last line moves one index to the

          # front and index 3 refers to the percentage instead of

          # the available space. Our fix is to count the elements

          # from the end, as the available space is the third one

          # from the end, and this idnex does not change when an

          # entry is split into two lines.

 

          return [lindex [lindex [split [exec df -k $dir] /n] end] end-2].0

      }

      HP-UX {

          return [lindex [lindex [split [exec bdf   $dir] /n] end] 3].0

      }

      AIX {

          return [lindex [lindex [split [exec df -k $dir] /n] end] 2].0

      }

      {Windows NT} - {Windows 95} {

          catch {

            set dir [file nativename $dir]

            set res [eval exec [auto_execok dir] [list $dir]]

            set line [lindex [split $res "/n"] end]

            if {[regexp -nocase {([0-9,/.]+)/s+(bytes|KB|MB)/s+} /

                  $line -> size type]} {

                set size [string map {, {}} $size]

                switch $type {

                  MB - mb { return [expr {$size * 1000.0}] }

                  KB - kb { return [expr {double($size)}] }

                  BYTES - bytes {

                      if {[string match {*.*} $size]} {

                        return [expr {$size / 1024.0}]

                      } else {

                        return [expr {double($size) / 1024.0}]

                      }

                  }

                }

            } else {

                error "Unable to extract free space for $dir from output of 'dir'"

            }

          }

          # Some error occured, assume we have at least 100MB

          return 100000.0

      }

      default {error "Unable to get disk free space on $::tcl_platform(os)"}

   }

 

2005/2/16

Double quotes compared to the list command.

set x {1 2}

=> 1 2

set y "$x 3"

=> 1 2 3

set y [concat $x 3]

=> 1 2 3

set z [list $x 3]

=> {1 2} 3

 

The distinction between list and concat becomes important when Tcl commands

are built dynamically. The basic rule is that list and lappend preserve

list structure, while concat (or double-quotes) eliminate one level of list structure.

The distinction can be subtle because there are examples where list and

concat return the same results. Unfortunately, this can lead to data-dependent

bugs.

 

lappend

The lappend command is unique among the list-related commands because

its first argument is the name of a list-valued variable, while all the other commands

take list values as arguments. You can call lappend with the name of an

undefined variable and the variable will be created.

 

Deleting a list element by value.

proc ldelete { list value } {

set ix [lsearch -exact $list $value]

if {$ix >= 0} {

return [lreplace $list $ix $ix]

} else {

return $list

}

}

 

 

Use split to turn input data into Tcl lists.

set line {welch:*:3116:100:Brent Welch:/usr/welch:/bin/csh}

split $line :

=> welch * 3116 100 {Brent Welch} /usr/welch /bin/csh

set line {this is "not a tcl list}

lindex $line 1

=> is

lindex $line 2

=> unmatched open quote in list

lindex [split $line] 2

=> "not

 

join

join { 1 {2 {3 3 3}} { 4 5 }}

=> 1 2 {3 3 3} 4 5

join [join { 1 {2 {3 3 3}} { 4 5 }}]

=> 1 2 3 3 3 4 5

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值