Provided by:
manpages-zh_1.5.1-1_all 
NAME
namespace - 建立及操作給命令和變量的上下文
` SYNOPSIS
namespace ?option? ?arg ...?
_________________________________________________________________
yz DESCRIPTION
namespace
命令讓你建立、訪問、和銷毀給命令和變量的獨立的上下文。名字空間的概-
z參見下悸WHAT IS A NAMESPACE? (什麼是名字空間) 章節。下惘C出了合法的
option 。注意你可以縮寫這些 option 。
namespace children ?namespace? ?pattern?
返回屬於名字空間 namespace 的所有子名字空間的一-
茼C表。如果未指定namespace,則返回當前名字空間的所有子名字空間。這-
茤R令返回完全制的(fully-qualified)的名字,它怚H ::
開始。如果給出了可選的 pattern ,則這-
茤R令只返回匹配通配符式樣模式的名字。確定實際使用的模式如下: 以
:: 開始的模式直接使用,否則把命令空間 namespace
(或當前名字空間的完全制的名字) 加在這蚍狾〞澈e情C
namespace code script
為以後執行稿本 script
而捕獲(Capture)當前的名字空間上下文。它返回一虓s稿本,在這-
茧痕G稿本中 script 被包裹在一 namespace inscope
命令中。新稿本有兩茷n的特性。漸,它可以在任何名字空間中被求-
A而導P script 在當前的名字空間(調用 namespace code命令的那-
茼W字空間)中被求C其次,可以向結果稿本添加補充的參數 並且它-
戔N被作為補充參數而傳遞給 script 。例如,假設在名字空間 ::a::b
中調用命令set script [namespace code {foo
bar}]。則可以在任何名字空間中執行 eval "$script x y" (假定
script 的w經被正確的傳遞進來) 而與命令 namespace eval ::a::b
{foo bar x y} 有相同的效果。這茤R令是必須有的,因為像 Tk
這樣的擴展一般在全局名字空間中執行回調稿本。一-
茼釦@用域的(scoped)命令把一-
茤R令和它的名字空間上下文一起捕獲,在這種方式下就能在以後正確的執行它。如何使用這-
茤R令建立回調稿本的例子參見SCOPED VALUES (有作用域的)章節。
namespace current
返回給當前名字空間的完全-
定的名字。全局名字空間的實際的名字是「」(一茠臟),但這-
茤R令為了編程者的方便而為全局名字空間返回 ::。
namespace delete ?namespace namespace ...?
刪除所有的名字空間 namespace
和這些名字空間包含的所有變量、過程、和子名字空間。如果在名字空間中一-
蚢L程正在執行,在這蚢L程返回之前這蚢L程保持存在;但是,會標記這-
茼W字空間來防止其他代碼通過名字查找它。如果一-
茼W字空間不存在,這茤R令返回一蚇欞~。如果未給出名字空間名字,這-
茤R令什麼也不做。
namespace eval namespace arg ?arg ...?
激活叫 namespace 的名字空間並在這茪W下文中對某些稿本進行求-
C如果這茼W字空間不存在,則建立它。如果指定了多於一 arg
參數,則用與
eval命令一樣的方式把這些參數串聯起來並用空格彼此分隔,並對結果進行求-
C
如果 namespace 有前導的名字空間-
定符並且有的前導名字空間不存在,則自動建立它怴C
namespace export ?-clear? ?pattern pattern ...?
指定從一-
茼W字空間中導出那些命令。導出的那些命令以後可以被其他名字空間用
namespace import 命令導入。在一茼W字空間中定義的命令和這-
茼W字空間以前導入的命令二者都可以被這-
茼W字空間導出。在執行namespace export 命令的時唌A這些(-
n導出的)命令不是必須已經被定義了。每 pattern
可以包含通配符式樣的特殊字符,但不可以包含任何名字空間-
定符。就是說,模式只能指定在當前(導出)的名字空間中的命令。把所有
pattern 添加到這茼W字空間的導出模式列表上。如果給出了 -clear
標誌,則在添加任何 pattern 參數之前,姜m這-
茼W字空間的導出模式列表為空。如果未給出 patterns 並且未給出
-clear標誌,這茤R令返回這茼W字空間當前的導出列表。
namespace forget ?pattern pattern ...?
刪除以前從一茼W字空間導入的命令。所有 pattern 都是一茤w的命令如
foo::x 或 a::b::p*。定的名字包含 ::並且用一茤峖h茼W字空間的名字-
制一茼W字。每 pattern 被一蚞犮X名字空間的名字所制,並且在-
定的名字的結束處可以有通配符式樣的特殊字符。通配字符可以不出現在名字空間的名字中。這-
茤R令-
漸查找匹配的導出命令。接著檢查是否有些命令是以前由當前名字空間導入的。如果有,這-
茤R令刪除相應的導入的命令。效果上,這茤R令撤消 namespace
import命令的動作。
namespace import ?-force? ?pattern pattern ...?
導入命令到一茼W字空間中。所有 pattern都是一茤w的命令如foo::x 或
a::p*。就是說,它包括一蚞犮X名字空間的名字,並且在-
定的名字的結束處可以有通配符式樣的特殊字符。通配字符可以不出現在名字空間的名字中。把所有匹配某-
pattern 字符串並且被它-
怐漲W字空間導出的命令添加到當前名字空間中。這是通過在當前名字空間中建立一-
虓s命令,這虓s命令指向在它的鴝l名字空間中的導出命令;當調用這-
虓s導入的命令的時唌A它調用那蚞犮X的命令。如果一蚞氻J的命令與一-
茞{存的命令有沖突,則這茤R令通常返回一蚇欞~。但是,如果給出了
-force 選項,在則導入命令將悄無聲息的替換現存的命令。namespace
import 命令有當前快照(snapshot)語義: 就是說,在-
n求(導入)的命令中,只導入在導出的名字空間中定義了的那些命令。換句話說,你只能導入在執行
namespace import 的時啈b一-
茼W字空間中(已經存在)的命令。如果此後又定義並導出了其他命令,則不會導入它-
怴C
namespace inscope namespace arg ?arg ...?
在一荅S定的名字空間的上下文中執行一-
蚑Z本。不希望編程者直接執行這茤R令;例如,在應用使用 namespace
code命令建立回調稿本,並且應用接著n向 Tk組件注冊它的時-
唌A隱式的生成對它的調用。除了有
lappend語義並且名字空間必須已經存在之外,namespace inscope命令與
namespace eval 命令非常相似。它把第一荌捊@為一-
茼C表來對待,接著把後悸漫狾陸捊@為適當的列表元素添加到第一-
荌捊漣應﹛Cnamespace inscope ::foo a x y z 等價於namespace
eval ::foo [concat a [list x y z]]。這 lappend>語義很-
n,因為釵h回調 稿本實際上是前綴。
namespace origin command
返回導入的命令 command所引用的鴝l命令的完全定的名字。當一-
茤R令被導入一茼W字空間的時唌A在這茼W字空間中建立一-
虓s命令,它指向在導出名字空間中的實際命令。如果一-
茤R令被導入到一茼W字空間的序列 a, b,...,n 之中,這裏每一-
茷慁簹漲W字空間只從前悸漲W字空間中導入命令,這茤R令返回在第一-
茼W字空間中的鴝l命令的完全定的名字 a。如果 command不引用一-
蚞氻J的命令,返回這(command)命令自己的完全定的名字。
namespace parent ?namespace?
返回給名字空間 namespace 的父名字空間的完全定的名字。如果未指定
namespace,返回當前名字空間的父名字空間的完全定的命令。
namespace qualifiers string
返回給 string 的所有前導的名字空間定符。定符是由
::分隔的名字空間的名字。對於 string ::foo::bar::x,這茤R令返回
::foo::bar,而對於 ::它返回一茠臟瞗C這茤R令與 namespace tail
命令互補。注意,它不檢查名字空間的名字事實上是否是目前定義的名字空間的名字。
namespace tail string
返回在一茤w的字符串尾部的簡單名字。定符是由
::分隔的名字空間的名字。對於 string ::foo::bar::x,這茤R令返回
x,而對於 ::它返回一茠臟瞗C這茤R令與 namespace
qualifiers命令互補。它不檢查名字空間的名字事實上是否是目前定義的名字空間的名字。
namespace which ?-command? ?-variable? name
把 name 作為一茤R令或者變量來查找並返回它的完全-
定的名字。例如,如果 name
在當前名字空間中不存在但在全局名字空間中存在,這-
茤R令返回在全局名字空間中的一荍馴定的名字。如果這-
茤R令或變量不存在,這-
茤R令返回空串。如果變量已經建立但未被定義,比如通過 variable
命令或通過在變量上trace(進行追蹤),這茤R令返回這蚥僆q的完全-
定的名字。如果未給出標誌,name被作為一-
茤R令的名字。關於名字解析的規則的解釋請參見下悸NAME RESOLUTION
(名字解析)章節。
Wr WHAT IS A NAMESPACE?
一茼W字空間是命令和變量的一荈隻X(collection)。它封裝命令和變量來確保它-
怳ㄦ|被其他名字空間中命令和變量所幹擾。Tcl 總是有一-
茬o樣的集合,它被引用為global namespace
(全局名字空間)。全局名字空間持有所有全局變量和命令。namespace
eval命令讓你建立一虓s的名字空間。例如,
namespace eval Counter {
namespace export bump
variable num 0
proc bump {} {
variable num
incr num
}
}
建立包含變量 num 和過程 bump 的一虓s的名字空間。在這-
茼W字空間中的命令和變量獨立於在同一-
茧{式中的其他命令和變量。例如,如果在全局名字空間中有一茈s
bump的命令,它不同的於在 Counter 名字空間中的 bump 命令。
名字空間變量類似於在 Tcl 中的全局變量。它-
怞s在於名字空間中的過程之外,但像在上悸漕狺l中展示的那樣,在同一-
茼W字空間中的過程可以通過 variable 命令訪問它。
名字空間是動態的。你可以在任意時-
埮W加及刪除命令和變量,所以你可以使用一系列 namespace
eval命令分幾次(over time)來建造一茼W字空間的內容。例如,下-
悸漱@系列命令與上戛i示的定義有相同的效果:
namespace eval Counter {
variable num 0
proc bump {} {
variable num
return [incr num]
}
}
namespace eval Counter {
proc test {args} {
return $args
}
}
namespace eval Counter {
rename test ""
}
注意在例子中向 Counter 名字空間增加了 test 過程,後來又用
rename命令把它刪除了。
在名字空間內可以又其他的名字空間,它怓O有層次的嵌套。一-
荋O套的名字空間被封裝在它的父名字空間中並且不會被其他名字空間所幹擾。
wWr QUALIFIED NAMES
每茼W字空間都有一茪憟誚W字比如history 或
::safe::interp。因為名字空間可以嵌套,使用-
定的名字來引用在名字空間中的命令、變量、和包含子名字空間。除了使用
::作為分隔符而不是 / 或 . 之外,定的(qualified)名字類似於給 Unix 檔案或
Tk 組件的有層次的路徑,最頂層或全局名字空間擁有名字「」 (一茠臟),而
:: 是它的同義詞。例如,名字 ::safe::interp::create 引用在名字空間
::safe 的子名字空間 interp 中的命令 create,::safe 是全局名字空間 ::
的子名字空間。
如果你打算從其他的名字空間中訪問命令和變量,你必須使用額外的語法。名字必須被包含它-
怐漲W字空間所定。例如我怚i以像下掖o樣訪問 Counter 的過程:
Counter::bump 5
Counter::Reset
我怚i以像下掖o樣訪問當前的 count (變量的):
puts "count = $Counter::num"
當一茼W字空間包含另一茠漁尕,n到達它的元素你可能需n多於一茠-
定符。如果我怞酗@茼W字空間 Foo,它包含名字空間 Counter,你可以像下-
掖o樣從全局名字空間調用它的 bump 過程:
Foo::Counter::bump 3
你還可以在建立和咿R名命令的時唻洏峏w的名字。例如,你可以像下掖o樣向
Foo增加一蚢L程:
proc Foo::Test {args} {return $args}
你可以像下掖o樣把同一蚢L程移動到另一茼W字空間中:
rename Foo::Test Bar::Test
我斨郅(C)ver)剩下的一些關於定的名字的-
n點。除了全局名字空間之外名字空間有非空的名字。除了作為名字空間分隔符,不允 ::
在簡單命令、變量、和名字空間名字中使用。在定的名字中忽略額外的 :
;就是說,兩茤峓韟h的 : 被作為一茼W字空間分隔符。在一-
定的變量或命令名字中的尾隨的 :: 引用叫做 {} 的變量或命令。但是忽略在一-
茤w的名字空間名中的尾隨的 ::。
NAME
一般的,所有接受變量和命令的名字的 Tcl 命令都支持-
定的名字。這意味著你可以把定的名字給這樣的命令如set、proc、rename、和
interp alias。如果你提供了以 :: 開始的一荍馴-
定的名字,對任何命令、變量、或名字空間多沒有問題。但是,如果這-
茼W字不以一 :: 開始(它是),Tcl 依據一茤T定的規則來查找它:
解析命令和變量名字總是-
漸在當前的名字空間中查找,接著在全局名字空間中查找。另一方-
情A解析名字空間總是在當前名字空間中查找。
在下列例子中,
set traceLevel 0
namespace eval Debug {
printTrace $traceLevel
}
Tcl 在名字空間 Debug 中查找
traceLevel接著在全局名字空間中查找,它以相同的方式查找命令
printTrace。如果一蚥僆q或命令的名字在這兩茪W下文中都找不到,則這-
茼W字是未定義的。為了使這一點絕對清楚,考慮下列例子:
set traceLevel 0
namespace eval Foo {
variable traceLevel 3
namespace eval Debug {
printTrace $traceLevel
}
}
這裏 Tcl 漸在名字空間 Foo::Debug 中查找
traceLevel。因為在這裏未找到,Tcl
接著在全局名字空間中查找。在名字解析過程中完全忽略了變量
Foo::traceLevel。
你可以使用 namespace which 命令來清除關於名字解析的任何問題:
namespace eval Foo::Debug {namespace which -variable traceLevel}
返回 ::traceLevel。另一方情A命令,
namespace eval Foo {namespace which -variable traceLevel}
返回 ::Foo::traceLevel.
如上-
探ㄓ峈漕獐芊A查找名字空間名字與變量和命令的名字不同。總是在當前名字空間中解析名字空間名字。這意味除非新名字空間的名字以一-
::開始,否則建立一虓s名字空間的 namespace eval
命令總是建立當前名字空間的一茪l名字空間。
Tcl 對你可以引用的變量、命令、或名字空間沒有訪問控制。如果你能提供一-
定的名字來通過名字解析規則解析到一茪葛嚏A你就可以訪問這茪葛嚏C
你可以通過 variable 命令從同一茼W字空間中的一蚢L程中訪問一-
茼W字空間變量。非常像 global 命令,它建立到名字空間變量的一-
茈誚a連接。如果需n,這茤R令還在當前的名字空間中建立這-
蚥僆q並初始化它。注意:global命令只建立到在全局名字空間中的變量的連接。如果你總是使用一-
蚞A當的定的名字來引用名字空間變量,則使用 variable 命令不是必須的。
JRO IMPORTING COMMANDS
名字空間經常用來表示庫。一些庫命令使用的如此頻繁以至於鍵入它怐-
定的名字是極其煩人的。例如, 假設在一茈]如 BLT 中的所有命令都包含在一-
茈s Blt 的名字空間中。則你可以像下掖o樣訪問這些命令:
Blt::graph .g -background red
Blt::table . .g 0,0
如果你頻繁使用 graph 和 table 命令,你可能希望訪問它怞茪ㄔ峊[
Blt::前綴。你可以通過把它導入到當前名字空間中的方式來達到此目的。例如:
namespace import Blt::*
這茖狺l把從
Blt名字空間導出的所有命令增加到當前名字空間上下文中,所以你可以像下-
掖o樣寫代碼:
graph .g -background red
table . .g 0,0
namespace import命令從一茼W字空間導入的命令只能是那茼W字空間中用
namespace export命令導出的命令。
從一茼W字空間導入釧R令一般是一-
蚚a主意,因為你不知道你將會得到些什麼。更好的方式是只導入你需-
n的命令。例如,命令
namespace import Blt::graph Blt::table
只把 graph 和 table 命令導入到當前上下文。
如果你n導入一茪w經存在的命令,你將得到一蚇欞~。這防止你從兩-
茪ㄕP的包導入同一茤R令。但是有的時(可能在調試時),你可能希望超越這-
制。你可能希望奐s發起(reissue) namespace import命令來導入(pick up)一-
虓s命令,而同名的命令在這-
茼W字空間中已經出現過了。在這種情況下,你可以使用 -force
選項,現存命令將悄無聲息的被覆寫(overwritten):
namespace import -force Blt::graph Blt::table
如果出於某種鴞],你打算停止使用導入的命令,你可以用 namespace forget
命令刪除它怴A例如:
namespace forget Blt::*
它在當前名子空間中查找從 Blt 導入的所有命令,如果找到則刪除它-
怴C否則,它什麼都不做。此後,訪問 Blt命令必須使用 Blt:: 前綴。
當你從導出(命令的)名字空間刪除一茤R令的時唌A例如:
rename Blt::graph ""
則從所有導入它的名字空間中自動刪除這茤R令。
XRO EXPORTING COMMANDS
你可以從一茼W字空間中導出命令,例如:
namespace eval Counter {
namespace export bump reset
variable Num 0
variable Max 100
proc bump {{by 1}} {
variable Num
incr Num $by
Check
return $Num
}
proc reset {} {
variable Num
set Num 0
}
proc Check {} {
variable Num
variable Max
if {$Num > $Max} {
error "too high!"
}
}
}
過程 bump 和 reset 被導出,所以當你從 Counter 名字空間導入的時唌A它-
抭Q包括在內。例如:
namespace import Counter::*
但是 Check 過程未被導出,所以它被導入操作所忽略。
namespace import,命令只導入被它怐漲W字空間導出的命令。namespace export
命令指定什麼命令可以被其他名字空間導入。如果一 namespace
import命令指定了一茈撲Q導出的命令,則不導入這茤R令。
SEE ALSO
variable(n)
r KEYWORDS
exported, internal, variable
[]
Hhh
[]
2001/10/12
m Linux manUpn:
http://cmpp.linuxforum.net