资源预览内容
第1页 / 共44页
第2页 / 共44页
第3页 / 共44页
第4页 / 共44页
第5页 / 共44页
第6页 / 共44页
第7页 / 共44页
第8页 / 共44页
第9页 / 共44页
第10页 / 共44页
亲,该文档总共44页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
TCL 名称空间(namespace)名称空间是命令和变量的集合。它封装命令和变量以确保不与其它名称空间中的命令和变量冲突。Tcl 总是有一个这样的集合,称为全局名称空间。全局名称空间保存全局变量和命令。namespace eval 命令用来创建新的名称空间。例如,namespace eval Counter namespace export bumpvariable num 0proc bump variable numincr num创建一个新的名称空间,包含变量 num 和过程 bump。此名称空间中的命令和变量与同一程序中的其它命令和变量相互独立。例如,如果在全局名称空间中有一个名为 bump 的命令,它与 Counter 名称空间中的 bump 命令不同。名称空间变量类似于 Tcl 中的全局变量。它们位于名称空间中过程的外面,在过程中可以通过 variable 命令来访问它们,如上例所示。名称空间是动态的。可以在任何时候添加和删除命令,所以可以通过一系列的 namespace eval 命令不时地构建名称空间的内容。例如,下列一系列的命令与上面定义的名称空间的效果相同:namespace eval Counter variable num 0proc bump variable numreturn incr numnamespace eval Counter proc test args return $argsnamespace eval Counter rename test 注意,过程 test 是被添加到名称空间 Counter 中的,而稍后通过 rename 命令删除它。名称空间中可以包含有其他的名称空间,所以它们是分层嵌套的。嵌套的名称空间被包裹在父名称空间中,而不能与其它名称空间有冲突。限定的命名每个名称空间都有一个 textual(文本上的)名字,如 history或:safe:interp。因为名称空间可以嵌套,使用限定的名字来引用包含在名称空间中的命令,变量和子名称空间。限定的名字类似于 Unix 文件或 Tk 组件的分层路径名,除了使用:而不是使用/或.作为分隔符之外。最顶层的或全局名称空间的名字为(空字符串) ,它的同义词为:。例如,名字:safe:interp:create 引用名称空间 interp 中的命令 create,而 interp 是名称空间:safe 的子名称空间,而:safe 又是全局名称空间:的子名称空间。如果想要访问另一个名称空间的命令和变量,必须使用一些额外的语法。这些命令或变量的名字必须用包含这些命令或变量的名称空间限定。从全局名称空间中,可以像下列那样访问 Counter 过程:Counter:bump 5Counter:Reset可以像这样访问当前的计数:puts count = $Counter:num当一个名称空间包含另一个名称空间时,则需要更多的限定的符以访问所需的元素。如果名称空间 Foo 包含名称空间 Counter,要从全局名称空间中调用 Counter 的 bump 过程,如下所示:Foo:Counter:bump 3当创建或重命名命令时,也可以使用限定的名字。例如,可以在名称空间 Foo 中添加一个过程:proc Foo:Test args return $args也可以把同一个过程从一个名称空间中移动另一个名称空间中:rename Foo:Test Bar:Test名称空间的名字不能为空,全局名称空间除外。在简单的命令,变量和名称空间的名字中不允许出现:,除了它作为名称空间分隔符之外。在限定的名字的任意分隔符中,额外的冒号会被忽略,比如,两个或多个冒号被为是一个名称空间分隔符。在限定的变量或命令名字后面尾随的:,表示引用的变量或命令的名字为。然而,限定的名称空间名字后面尾随的:,则被忽略。名称解析一般来说,所有的 Tcl 命令和变量的名字都支持限定的名字。意思即是,可以给 set,pro,rename 和 interp alias 这些命令一个限定的名字。如果提供一个以:开始的完全限定的名字,对所想要使用的命令,变量或名字空间没有影响。然而,如果名字不是以:开始的(即是相对的) ,则查找这些名字时 Tcl 遵守基本的规则:变量名总是首先在当前名称空间中查找,然后再在全局名称空间中查找。命令名总是首先在当前名称空间中查找。如果在当前名称空间中没有查找到,则在每个名称空间中在当前名称空间的路径(默认为空)中查找。如果也没有找到,则在全局名称空间中查找命令名(或者如果在全局名称空间没有找到,则由 unknown 命令处理) 。名称空间名字,换句话说,只是在当前名称空间中查找。在下列的例子中:set traceLevel 0namespace eval Debug printTrace $traceLevelTcl 在 Debug 名称空间中查找 traceLevel,然后面全局名称空间中查找。查找 printTrace 命令的方法相同。如果在当前或全局名称空间中没有查找到变量或命令的名字,则此名字是未定义的。为了使这一观点清楚,考虑下面的例子:set traceLevel 0namespace eval Foo variable traceLevel 3namespace eval Debug printTrace $traceLevelTcl 首先在名称空间 Foo:Debug 中查找 traceLevel。在此名称空间没有查找到,则在全局名称空间中查找。变量Foo:traceLevel 在名字解析过程中完全被忽略。可以使用 namespace which 命令以澄清有关名称解析的问题。例如,下列的命令:namespace eval Foo:Debug namespace which -variable traceLevel返回:traceLevel。另一方面,命令:namespace eval Foo namespace which -variable traceLevel返回:Foo:traceLevel。正如上文所述的,名称空间名字的查找与变量和命令的名称查找不同。名称空间名称总是在当前名称空间中解决。这意味着,例如,namespace eval 命令创建一个新的名称空间,总是当前名称空间的子名称空间,除非新的名称空间名称以:开始。Tcl 没有访问控制,以限制可以引用哪些变量、命令或名称空间。如果提供一个限定的名称,根据上述的解析规则将被解析为一个元素的名称,可以访问该元素。通过使用 variable 命令,可以在同一个名称空间中的过程中访问名称空间变量。与 global 命令相似,这创建名称空间变量的局部地引用。如有需要,也可以在当前名称空间中创建变量并初始化。注意,global 命令只创建对全局名称空间中的变量的指向。 ,如果您总是使用适当的限定的名称来引用名称空间变量,则不需要使用variable 命令。 导入命令名称空间通常用于表示库。某些库命令频繁地被使用,所以输入他们的限定的名称有时很烦。例如,假设像 BLT 包中的所有命令包含在名称空间 Blt 中。则,可能访问这些命令,会象这样:Blt:graph .g -background redBlt:table . .g 0,0如果经常使用 graph 和 table 命令,可能想不用输入 Blt:前缀访问它们。可以通过导入命令到当前名称空间中,如:namespace import Blt:*这会将 Blt 名称空间中所有导出的命令添加当前名称空间上下文中,因此可以编写像下面的这样的代码:graph .g -background redtable . .g 0,0namespace import 命令只从名称空间中导入用 namespace export 命令导出的命令。 从名称空间导入每个命令通常不是一个好主意,因为您不知道你会得到什么。最好只导入您需要的特定的命令。例如,命令:namespace import Blt:graph Blt:table只导入 graph 和 table 命令到当前上下文中。如果试图导入已存在的命令,会发生错误。这预防从两个不同的包中导入相同的命令。但有时(可能进行调试时),您可能想要绕过此限制。您可能想重新发出 namespace import 命令,以把已出现在名称空间中的命令作为新的命令使用。在这种情况下,您可以使用-force 选项,而现有的命令将被覆盖:namespace import -force Blt:graph Blt:table如果因为某些的原因而要停止使用导入的命令,您可以使用namespace forget 命令将其删除,如下所示:namespace forget Blt:*这将搜索当前名称空间中从 Blt 导入的任何命令。如果找到,则删除它们。否则,不执行任何操作。此后,Blt 的命令必须用Blt:前缀来访问。当你删除从名称空间中导出的命令时,如下所示:rename Blt:graph 此命令将自动删除从导入它的所有名称空间中的 graph 命令。导出命令可以从名称空间中导出命令,如下所示:namespace eval Counter namespace export bump resetvariable Num 0variable Max 100proc bump by 1 variable Numincr Num $byCheckreturn $Numproc reset variable Numset Num 0proc Check variable Num variable Maxif $Num $Max error too high!导出 bump 和 reset 过程,所以从 Counter 名称空间导入时,它们就会被包括,像:namespace import Counter:*但是,Check 过程不被导出,所以导入操作会忽略它。namespace import 命令只导入在名称空间中被声明为导出的命令。namespace export 命令指定哪些命令可以被其他名称空间导入。如果 namespace import 命令指定一个并不是被声明为导出的命令,则此命令将不会被导入。脚本的作用域namespace code 命令是在名称空间中脚本可以被打包用于评估的方法,而不是在名称空间中创建。 它最常用于在全局上下文中创建事件处理程序、Tk 绑定和用于评估的跟踪信息。例如,下面的代码表示如何直接跟踪变量回调到当前名称空间中:namespace eval a variable bproc theTraceCallback n1 n2 op upvar 1 $n1 varputs the value of $n1 has changed to $varreturntrace variable b w namespace code theTraceCallbackset a:b c当被执行时,它打印信息:the value of a:b has changed to c集成 ENSEMBLESnamespace ensemble 用于创建和操作集成的命令,子命令组合在一起而组成的集合。当集成的命令被创建时,此命令通常从当前名称空间中创建集(虽然这是可配置的) 。注意,可以有任意数量的与任何的名称空间(包括空,默认情况下)相关联的集成命令,但当与所有集成的命令相关联的名称空间相被删除时,则集成的命令将被删除。集成的命令与和它相关联
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号