Provided by: manpages-zh_1.6.3.6-1_all bug

NAME

       namespace - 建立及操作給命令和變數的上下文

總覽 SYNOPSIS

       namespace ?option? ?arg ...?
_________________________________________________________________

描述 DESCRIPTION

       namespace     命令讓你建立、訪問、和銷燬給命令和變數的獨立的上下文。名字空間的概述參見下面
       的WHAT IS A NAMESPACE? (什麼是名字空間) 章節。下面列出了合法的 option 。注意你可以縮寫這些
       optionnamespace children ?namespace? ?pattern?
              返回屬於名字空間  namespace 的所有子名字空間的一個列表。如果未指定namespace,則返回
              當前名字空間的所有子名字空間。這個命令返回完全限制的(fully-qualified)的名字,它們以
              :: 開始。如果給出了可選的 pattern  ,則這個命令只返回匹配萬用字元式樣模式的名字。確
              定實際使用的模式如下: 以 ::  開始的模式直接使用,否則把命令空間 namespace   (或當前
              名字空間的完全限制的名字) 加在這個模式的前面。

       namespace code script
              為以後執行指令碼 script 而捕獲(Capture)當前的名字空間上下文。它返回一個新指令碼,在
              這個結果指令碼中 script  被包裹在一個 namespace inscope  命令中。新指令碼有兩個重要
              的特性。首先,它可以在任何名字空間中被求值,而導致   script   在當前的名字空間(呼叫
              namespace     code命令的那個名字空間)中被求值。其次,可以向結果指令碼新增補充的引數
              並且它們將被作為補充引數而傳遞給  script    。例如,假設在名字空間  ::a::b 中呼叫命
              令set script [namespace code {foo bar}]。則可以在任何名字空間中執行 eval "$script x
              y"    (假定  script   的值已經被正確的傳遞進來) 而與命令 namespace eval ::a::b {foo
              bar x y} 有相同的效果。這個命令是必須有的,因為象 Tk   這樣的擴充套件一般在全域性名
              字空間中執行回撥指令碼。一個有作用域的(scoped)命令把一個命令和它的名字空間上下文一
              起捕獲,在這種方式下就能在以後正確的執行它。如何使用這個命令建立回撥指令碼的例子參
              見SCOPED VALUES (有作用域的值)章節。

       namespace current
              返回給當前名字空間的完全限定的名字。全域性名字空間的實際的名字是“”(一個空串),但這
              個命令為了程式設計者的方便而為全域性名字空間返回 ::namespace delete ?namespace namespace ...?
              刪除所有的名字空間 namespace   和這些名字空間包含的所有變數、過程、和子名字空間。如
              果在名字空間中一個過程正在執行,在這個過程返回之前這個過程保持存在;但是,會標記這
              個名字空間來防止其他程式碼透過名字查詢它。如果一個名字空間不存在,這個命令返回一個
              錯誤。如果未給出名字空間名字,這個命令什麼也不做。

       namespace eval namespace arg ?arg ...?
              啟用叫  namespace  的名字空間並在這個上下文中對某些指令碼進行求值。如果這個名字空間
              不存在,則建立它。如果指定了多於一個 arg    引數,則用與 eval命令一樣的方式把這些引
              數串聯起來並用空格彼此分隔,並對結果進行求值。

              如果 namespace  有前導的名字空間限定符並且有的前導名字空間不存在,則自動建立它們。

       namespace export ?-clear? ?pattern pattern ...?
              指定從一個名字空間中匯出那些命令。匯出的那些命令以後可以被其他名字空間用  namespace
              import 命令匯入。在一個名字空間中定義的命令和這個名字空間以前匯入的命令二者都可以被
              這個名字空間匯出。在執行namespace  export  命令的時候,這些(要匯出的)命令不是必須已
              經被定義了。每個 pattern   可以包含萬用字元式樣的特殊字元,但不可以包含任何名字空間
              限定符。就是說,模式只能指定在當前(匯出)的名字空間中的命令。把所有 pattern   新增到
              這個名字空間的匯出模式列表上。如果給出了 -clear  標誌,則在新增任何    pattern 引數
              之前,重置這個名字空間的匯出模式列表為空。如果未給出  patterns  並且未給出 -clear標
              誌,這個命令返回這個名字空間當前的匯出列表。

       namespace forget ?pattern pattern ...?
              刪除以前從一個名字空間匯入的命令。所有  pattern  都是一個限定的命令如   foo::xa::b::p*。限定的名字包含 ::並且用一個或多個名字空間的名字限制一個名字。每個 pattern
              被一個匯出名字空間的名字所限制,並且在限定的名字的結束處可以有萬用字元式樣的特殊字
              元。通配字元可以不出現在名字空間的名字中。這個命令首先查詢匹配的匯出命令。接著檢查
              是否有些命令是以前由當前名字空間匯入的。如果有,這個命令刪除相應的匯入的命令。效果
              上,這個命令撤消 namespace import命令的動作。

       namespace import ?-force? ?pattern pattern ...?
              匯入命令到一個名字空間中。所有   pattern都是一個限定的命令如foo::xa::p*。就是
              說,它包括一個匯出名字空間的名字,並且在限定的名字的結束處可以有萬用字元式樣的特殊
              字元。通配字元可以不出現在名字空間的名字中。把所有匹配某個 pattern 字串並且被它們的
              名字空間匯出的命令新增到當前名字空間中。這是透過在當前名字空間中建立一個新命令,這
              個新命令指向在它的原始名字空間中的匯出命令;當呼叫這個新匯入的命令的時候,它呼叫那
              個匯出的命令。如果一個匯入的命令與一個現存的命令有衝突,則這個命令通常返回一個錯
              誤。但是,如果給出了 -force 選項,在則匯入命令將悄無聲息的替換現存的命令。namespace
              import  命令有當前快照(snapshot)語義:  就是說,在要求(匯入)的命令中,只匯入在匯出的
              名字空間中定義了的那些命令。換句話說,你只能匯入在執行  namespace import 的時候在一
              個名字空間中(已經存在)的命令。如果此後又定義並匯出了其他命令,則不會匯入它們。

       namespace inscope namespace arg ?arg ...?
              在一個特定的名字空間的上下文中執行一個指令碼。不希望程式設計者直接執行這個命令;例
              如,在應用使用  namespace code命令建立回撥指令碼,並且應用接著要向 Tk元件註冊它的時
              候,隱式的生成對它的呼叫。除了有 lappend語義並且名字空間必須已經存在之外,namespace
              inscope命令與 namespace eval 命令非常相似。它把第一個引數作為一個列表來對待,接著把
              後面的所有引數作為適當的列表元素新增到第一個引數的尾部。namespace inscope ::foo a x
              y z 等價於namespace eval ::foo [concat a [list x y z]]。這個 lappend>語義很重要,因
              為許多回調 指令碼實際上是字首。

       namespace origin command
              返回匯入的命令  command所引用的原始命令的完全限定的名字。當一個命令被匯入一個名字空
              間的時候,在這個名字空間中建立一個新命令,它指向在匯出名字空間中的實際命令。如果一
              個命令被匯入到一個名字空間的序列 a, b,...,n  之中,這裡每一個後續的名字空間只從前面
              的名字空間中匯入命令,這個命令返回在第一個名字空間中的原始命令的完全限定的名字
              a。如果 command不引用一個匯入的命令,返回這個(command)命令自己的完全限定的名字。

       namespace parent ?namespace?
              返回給名字空間 namespace 的父名字空間的完全限定的名字。如果未指定 namespace,返回當
              前名字空間的父名字空間的完全限定的命令。

       namespace qualifiers string
              返回給  string  的所有前導的名字空間限定符。限定符是由 ::分隔的名字空間的名字。對於
              string ::foo::bar::x,這個命令返回 ::foo::bar,而對於  ::它返回一個空串。這個命令與
              namespace tail 命令互補。注意,它不檢查名字空間的名字事實上是否是目前定義的名字空間
              的名字。

       namespace tail string
              返回在一個限定的字串尾部的簡單名字。限定符是由 ::分隔的名字空間的名字。對於  string
              ::foo::bar::x,這個命令返回    x,而對於   ::它返回一個空串。這個命令與   namespace
              qualifiers命令互補。它不檢查名字空間的名字事實上是否是目前定義的名字空間的名字。

       namespace which ?-command? ?-variable? namename  作為一個命令或者變數來查詢並返回它的完全限定的名字。例如,如果 name 在當前
              名字空間中不存在但在全域性名字空間中存在,這個命令返回在全域性名字空間中的一個完全
              限定的名字。如果這個命令或變數不存在,這個命令返回空串。如果變數已經建立但未被定
              義,比如透過 variable 命令或透過在變數上trace(進行追蹤),這個命令返回這個變數的完全
              限定的名字。如果未給出標誌,name被作為一個命令的名字。關於名字解析的規則的解釋請參
              見下面的NAME RESOLUTION (名字解析)章節。

什麼名字空間 WHAT IS A NAMESPACE?

       一個名字空間是命令和變數的一個集合(collection)。它封裝命令和變數來確保它們不會被其他名字空
       間中命令和變數所幹擾。Tcl 總是有一個這樣的集合,它被引用為global  namespace  (全域性名字空
       間)。全域性名字空間持有所有全域性變數和命令。namespace      eval命令讓你建立一個新的名字空
       間。例如,
              namespace eval Counter {
                  namespace export bump
                  variable num 0

                  proc bump {} {
                      variable num
                      incr num
                  }
              }
       建立包含變數 num  和過程 bump 的一個新的名字空間。在這個名字空間中的命令和變數獨立於在同一
       個程式中的其他命令和變數。例如,如果在全域性名字空間中有一個叫    bump的命令,它不同的於在
       Counter 名字空間中的 bump  命令。

       名字空間變數類似於在 Tcl  中的全域性變數。它們存在於名字空間中的過程之外,但象在上面的例子
       中展示的那樣,在同一個名字空間中的過程可以透過 variable 命令訪問它。

       名字空間是動態的。你可以在任意時候增加及刪除命令和變數,所以你可以使用一系列     namespace
       eval命令分幾次(over  time)來建造一個名字空間的內容。例如,下面的一系列命令與上面展示的定義
       有相同的效果:
              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命令把它刪除了。

       在名字空間內可以又其他的名字空間,它們是有層次的巢狀。一個巢狀的名字空間被封裝在它的父名字
       空間中並且不會被其他名字空間所幹擾。

限定的名字 QUALIFIED NAMES

       每個名字空間都有一個文字名字比如history::safe::interp。因為名字空間可以巢狀,使用限定
       的名字來引用在名字空間中的命令、變數、和包含子名字空間。除了使用 ::作為分隔符而不是 /.
       之外,限定的(qualified)名字類似於給 Unix 檔案或 Tk  元件的有層次的路徑,最頂層或全域性名字
       空間擁有名字“” (一個空串),而 :: 是它的同義詞。例如,名字 ::safe::interp::create  引用在名
       字空間 ::safe 的子名字空間 interp 中的命令 create::safe 是全域性名字空間  ::  的子名字空
       間。

       如果你打算從其他的名字空間中訪問命令和變數,你必須使用額外的語法。名字必須被包含它們的名字
       空間所限定。例如我們可以象下面這樣訪問 Counter 的過程:
              Counter::bump 5
              Counter::Reset
       我們可以象下面這樣訪問當前的 count (變數的值):
              puts "count = $Counter::num"
       當一個名字空間包含另一個的時候,要到達它的元素你可能需要多於一個的限定符。如果我們有一個名
       字空間 Foo,它包含名字空間 Counter,你可以象下面這樣從全域性名字空間呼叫它的 bump 過程:
              Foo::Counter::bump 3

       你還可以在建立和重新命名命令的時候使用限定的名字。例如,你可以象下面這樣向   Foo增加一個過
       程:
              proc Foo::Test {args} {return $args}
       你可以象下面這樣把同一個過程移動到另一個名字空間中:
              rename Foo::Test Bar::Test

       我們覆蓋(cover)剩下的一些關於限定的名字的要點。除了全域性名字空間之外名字空間有非空的名
       字。除了作為名字空間分隔符,不允許  ::  在簡單命令、變數、和名字空間名字中使用。在限定的名
       字中忽略額外的 : ;就是說,兩個或更多的 : 被作為一個名字空間分隔符。在一個限定的變數或命令
       名字中的尾隨的 :: 引用叫做 {} 的變數或命令。但是忽略在一個限定的名字空間名中的尾隨的 ::

NAME

       一般的,所有接受變數和命令的名字的  Tcl 命令都支援限定的名字。這意味著你可以把限定的名字給
       這樣的命令如setprocrename、和 interp alias。如果你提供了以  ::  開始的一個完全限定的名
       字,對任何命令、變數、或名字空間多沒有問題。但是,如果這個名字不以一個 ::    開始(它是相對
       ),Tcl 依據一個固定的規則來查詢它:  解析命令和變數名字總是首先在當前的名字空間中查詢,接
       著在全域性名字空間中查詢。另一方面,解析名字空間總是在當前名字空間中查詢。

       在下列例子中,
              set traceLevel 0
              namespace eval Debug {
                  printTrace $traceLevel
              }
       Tcl  在名字空間  Debug 中查詢 traceLevel接著在全域性名字空間中查詢,它以相同的方式查詢命令
       printTrace。如果一個變數或命令的名字在這兩個上下文中都找不到,則這個名字是未定義的。為了使
       這一點絕對清楚,考慮下列例子:
              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。另一方面,命令,
              namespace eval Foo {namespace which -variable traceLevel}
       返回 ::Foo::traceLevel.

       如上面提及的那樣,查詢名字空間名字與變數和命令的名字不同。總是在當前名字空間中解析名字空間
       名字。這意味除非新名字空間的名字以一個  ::開始,否則建立一個新名字空間的 namespace eval 命
       令總是建立當前名字空間的一個子名字空間。

       Tcl 對你可以引用的變數、命令、或名字空間沒有訪問控制。如果你能提供一個限定的名字來透過名字
       解析規則解析到一個元素,你就可以訪問這個元素。

       你可以透過 variable  命令從同一個名字空間中的一個過程中訪問一個名字空間變數。非常象 global
       命令,它建立到名字空間變數的一個本地連線。如果需要,這個命令還在當前的名字空間中建立這個變
       數並初始化它。注意:global命令只建立到在全域性名字空間中的變數的連線。如果你總是使用一個適
       當的限定的名字來引用名字空間變數,則使用 variable 命令不是必須的。

匯入命令 IMPORTING COMMANDS

       名字空間經常用來表示庫。一些庫命令使用的如此頻繁以至於鍵入它們的限定的名字是極其煩人的。例
       如,  假設在一個包如 BLT 中的所有命令都包含在一個叫 Blt 的名字空間中。則你可以象下面這樣訪
       問這些命令:
              Blt::graph .g -background red
              Blt::table . .g 0,0
       如果你頻繁使用 graphtable  命令,你可能希望訪問它們而不用加  Blt::字首。你可以透過把它
       匯入到當前名字空間中的方式來達到此目的。例如:
              namespace import Blt::*
       這個例子把從 Blt名字空間匯出的所有命令增加到當前名字空間上下文中,所以你可以象下面這樣寫程
       式碼:
              graph .g -background red
              table . .g 0,0
       namespace import命令從一個名字空間匯入的命令只能是那個名字空間中用 namespace  export命令匯
       出的命令。

       從一個名字空間匯入所有命令一般是一個壞主意,因為你不知道你將會得到些什麼。更好的方式是隻匯
       入你需要的命令。例如,命令
              namespace import Blt::graph Blt::table
       只把 graphtable  命令匯入到當前上下文。

       如果你要匯入一個已經存在的命令,你將得到一個錯誤。這防止你從兩個不同的包匯入同一個命令。但
       是有的時候(可能在除錯時),你可能希望超越這個限制。你可能希望重新發起(reissue)    namespace
       import命令來匯入(pick  up)一個新命令,而同名的命令在這個名字空間中已經出現過了。在這種情況
       下,你可以使用 -force   選項,現存命令將悄無聲息的被覆寫(overwritten):
              namespace import -force Blt::graph Blt::table
       如果出於某種原因,你打算停止使用匯入的命令,你可以用 namespace forget 命令刪除它們,例如:
              namespace forget Blt::*
       它在當前名子空間中查詢從   Blt  匯入的所有命令,如果找到則刪除它們。否則,它什麼都不做。此
       後,訪問 Blt命令必須使用 Blt::  字首。

       當你從匯出(命令的)名字空間刪除一個命令的時候,例如:
              rename Blt::graph ""
       則從所有匯入它的名字空間中自動刪除這個命令。

匯出命令 EXPORTING COMMANDS

       你可以從一個名字空間中匯出命令,例如:
              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!"
                      }
                  }
              }
       過程 bumpreset  被匯出,所以當你從 Counter 名字空間匯入的時候,它們被包括在內。例如:
              namespace import Counter::*
       但是 Check  過程未被匯出,所以它被匯入操作所忽略。

       namespace import,命令只匯入被它們的名字空間匯出的命令。namespace export  命令指定什麼命令
       可以被其他名字空間匯入。如果一個  namespace import命令指定了一個未被匯出的命令,則不匯入這
       個命令。

參見 SEE ALSO

       variable(n)

關鍵字 KEYWORDS

       exported, internal, variable

[中文版維護人]

       寒蟬退士

[中文版最新更新]

       2001/10/12

《中國 Linux 論壇 man 手冊頁翻譯計劃》:

       http://cmpp.linuxforum.net

       本頁面中文版由中文 man 手冊頁計劃提供。
       中文 man 手冊頁計劃:https://github.com/man-pages-zh/manpages-zh