'\" '\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies '\" Copyright (c) 1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: namespace.n,v 1.2 2003/11/24 05:09:59 bbbush Exp $ '\" '\" The definitions below are for supplemental macros used in Tcl/Tk '\" manual entries. '\" '\" .AP type name in/out ?indent? '\" Start paragraph describing an argument to a library procedure. '\" type is type of argument (int, etc.), in/out is either "in", "out", '\" or "in/out" to describe whether procedure reads or modifies arg, '\" and indent is equivalent to second arg of .IP (shouldn't ever be '\" needed; use .AS below instead) '\" '\" .AS ?type? ?name? '\" Give maximum sizes of arguments for setting tab stops. Type and '\" name are examples of largest possible arguments that will be passed '\" to .AP later. If args are omitted, default tab stops are used. '\" '\" .BS '\" Start box enclosure. From here until next .BE, everything will be '\" enclosed in one large box. '\" '\" .BE '\" End of box enclosure. '\" '\" .CS '\" Begin code excerpt. '\" '\" .CE '\" End code excerpt. '\" '\" .VS ?version? ?br? '\" Begin vertical sidebar, for use in marking newly-changed parts '\" of man pages. The first argument is ignored and used for recording '\" the version when the .VS was added, so that the sidebars can be '\" found and removed when they reach a certain age. If another argument '\" is present, then a line break is forced before starting the sidebar. '\" '\" .VE '\" End of vertical sidebar. '\" '\" .DS '\" Begin an indented unfilled display. '\" '\" .DE '\" End of indented unfilled display. '\" '\" .SO '\" Start of list of standard options for a Tk widget. The '\" options follow on successive lines, in four columns separated '\" by tabs. '\" '\" .SE '\" End of list of standard options for a Tk widget. '\" '\" .OP cmdName dbName dbClass '\" Start of description of a specific option. cmdName gives the '\" option's name as specified in the class command, dbName gives '\" the option's name in the option database, and dbClass gives '\" the option's class in the option database. '\" '\" .UL arg1 arg2 '\" Print arg1 underlined, then print arg2 normally. '\" '\" RCS: @(#) $Id: namespace.n,v 1.2 2003/11/24 05:09:59 bbbush Exp $ '\" '\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. .if t .wh -1.3i ^B .nr ^l \n(.l .ad b '\" # Start an argument description .de AP .ie !"\\$4"" .TP \\$4 .el \{\ . ie !"\\$2"" .TP \\n()Cu . el .TP 15 .\} .ta \\n()Au \\n()Bu .ie !"\\$3"" \{\ \&\\$1 \\fI\\$2\\fP (\\$3) .\".b .\} .el \{\ .br .ie !"\\$2"" \{\ \&\\$1 \\fI\\$2\\fP .\} .el \{\ \&\\fI\\$1\\fP .\} .\} .. '\" # define tabbing values for .AP .de AS .nr )A 10n .if !"\\$1"" .nr )A \\w'\\$1'u+3n .nr )B \\n()Au+15n .\" .if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n .nr )C \\n()Bu+\\w'(in/out)'u+2n .. .AS Tcl_Interp Tcl_CreateInterp in/out '\" # BS - start boxed text '\" # ^y = starting y location '\" # ^b = 1 .de BS .br .mk ^y .nr ^b 1u .if n .nf .if n .ti 0 .if n \l'\\n(.lu\(ul' .if n .fi .. '\" # BE - end boxed text (draw box now) .de BE .nf .ti 0 .mk ^t .ie n \l'\\n(^lu\(ul' .el \{\ .\" Draw four-sided box normally, but don't draw top of .\" box if the box started on an earlier page. .ie !\\n(^b-1 \{\ \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .el \}\ \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .\} .fi .br .nr ^b 0 .. '\" # VS - start vertical sidebar '\" # ^Y = starting y location '\" # ^v = 1 (for troff; for nroff this doesn't matter) .de VS .if !"\\$2"" .br .mk ^Y .ie n 'mc \s12\(br\s0 .el .nr ^v 1u .. '\" # VE - end of vertical sidebar .de VE .ie n 'mc .el \{\ .ev 2 .nf .ti 0 .mk ^t \h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' .sp -1 .fi .ev .\} .nr ^v 0 .. '\" # Special macro to handle page bottom: finish off current '\" # box/sidebar if in box/sidebar mode, then invoked standard '\" # page bottom macro. .de ^B .ev 2 'ti 0 'nf .mk ^t .if \\n(^b \{\ .\" Draw three-sided box if this is the box's first page, .\" draw two sides but no top otherwise. .ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .\} .if \\n(^v \{\ .nr ^x \\n(^tu+1v-\\n(^Yu \kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c .\} .bp 'fi .ev .if \\n(^b \{\ .mk ^y .nr ^b 2 .\} .if \\n(^v \{\ .mk ^Y .\} .. '\" # DS - begin display .de DS .RS .nf .sp .. '\" # DE - end display .de DE .fi .RE .sp .. '\" # SO - start of list of standard options .de SO .SH "STANDARD OPTIONS" .LP .nf .ta 5.5c 11c .ft B .. '\" # SE - end of list of standard options .de SE .fi .ft R .LP See the \\fBoptions\\fR manual entry for details on the standard options. .. '\" # OP - start of full description for a single option .de OP .LP .nf .ta 4c Command-Line Name: \\fB\\$1\\fR Database Name: \\fB\\$2\\fR Database Class: \\fB\\$3\\fR .fi .IP .. '\" # CS - begin code excerpt .de CS .RS .nf .ta .25i .5i .75i 1i .. '\" # CE - end code excerpt .de CE .fi .RE .. .de UL \\$1\l'|0\(ul'\\$2 .. .TH namespace 3tcl 8.0 Tcl "Tcl Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME namespace \- 建立及操作給命令和變數的上下文 .SH "總覽 SYNOPSIS" \fBnamespace \fR?\fIoption\fR? ?\fIarg ...\fR? .BE .SH "描述 DESCRIPTION" .PP \fBnamespace\fR 命令讓你建立、訪問、和銷燬給命令和變數的獨立的上下文。名字空間的概述參見下面的\fBWHAT IS A NAMESPACE?\fR (什麼是名字空間) 章節。下面列出了合法的 \fIoption \fR。注意你可以縮寫這些 \fIoption \fR。 .TP \fBnamespace children \fR?\fInamespace\fR? ?\fIpattern\fR? 返回屬於名字空間 \fInamespace \fR的所有子名字空間的一個列表。如果未指定\fInamespace\fR,則返回當前名字空間的所有子名字空間。這個命令返回完全限制的(fully-qualified)的名字,它們以 \fB:: \fR開始。如果給出了可選的 \fIpattern\fR ,則這個命令只返回匹配萬用字元式樣模式的名字。確定實際使用的模式如下: 以 \fB::\fR 開始的模式直接使用,否則把命令空間 \fInamespace\fR (或當前名字空間的完全限制的名字) 加在這個模式的前面。 .TP \fBnamespace code \fIscript\fR 為以後執行指令碼 \fIscript \fR而捕獲(Capture)當前的名字空間上下文。它返回一個新指令碼,在這個結果指令碼中 \fIscript\fR 被包裹在一個 \fBnamespace inscope\fR 命令中。新指令碼有兩個重要的特性。首先,它可以在任何名字空間中被求值,而導致 \fIscript\fR 在當前的名字空間(呼叫 \fBnamespace code\fR命令的那個名字空間)中被求值。其次,可以向結果指令碼新增補充的引數 並且它們將被作為補充引數而傳遞給 \fIscript\fR 。例如,假設在名字空間 \fB::a::b\fR 中呼叫命令\fBset script [namespace code {foo bar}]\fR。則可以在任何名字空間中執行 \fBeval "$script x y"\fR (假定 \fBscript\fR 的值已經被正確的傳遞進來) 而與命令 \fBnamespace eval ::a::b {foo bar x y} \fR有相同的效果。這個命令是必須有的,因為象 Tk 這樣的擴充套件一般在全域性名字空間中執行回撥指令碼。一個有作用域的(scoped)命令把一個命令和它的名字空間上下文一起捕獲,在這種方式下就能在以後正確的執行它。如何使用這個命令建立回撥指令碼的例子參見\fBSCOPED VALUES\fR (有作用域的值)章節。 .TP \fBnamespace current\fR 返回給當前名字空間的完全限定的名字。全域性名字空間的實際的名字是“”(一個空串),但這個命令為了程式設計者的方便而為全域性名字空間返回 \fB::\fR。 .TP \fBnamespace delete \fR?\fInamespace namespace ...\fR? 刪除所有的名字空間 \fInamespace\fR 和這些名字空間包含的所有變數、過程、和子名字空間。如果在名字空間中一個過程正在執行,在這個過程返回之前這個過程保持存在;但是,會標記這個名字空間來防止其他程式碼透過名字查詢它。如果一個名字空間不存在,這個命令返回一個錯誤。如果未給出名字空間名字,這個命令什麼也不做。 .TP \fBnamespace eval\fR \fInamespace arg\fR ?\fIarg ...\fR? 啟用叫 \fInamespace\fR 的名字空間並在這個上下文中對某些指令碼進行求值。如果這個名字空間不存在,則建立它。如果指定了多於一個 \fIarg\fR 引數,則用與 \fBeval\fR命令一樣的方式把這些引數串聯起來並用空格彼此分隔,並對結果進行求值。 .br .sp 如果 \fInamespace\fR 有前導的名字空間限定符並且有的前導名字空間不存在,則自動建立它們。 .TP \fBnamespace export \fR?\-\fBclear\fR? ?\fIpattern pattern ...\fR? 指定從一個名字空間中匯出那些命令。匯出的那些命令以後可以被其他名字空間用 \fBnamespace import\fR 命令匯入。在一個名字空間中定義的命令和這個名字空間以前匯入的命令二者都可以被這個名字空間匯出。在執行\fBnamespace export\fR 命令的時候,這些(要匯出的)命令不是必須已經被定義了。每個 \fIpattern\fR 可以包含萬用字元式樣的特殊字元,但不可以包含任何名字空間限定符。就是說,模式只能指定在當前(匯出)的名字空間中的命令。把所有 \fIpattern \fR新增到這個名字空間的匯出模式列表上。如果給出了 -\fBclear\fR 標誌,則在新增任何 \fIpattern\fR 引數之前,重置這個名字空間的匯出模式列表為空。如果未給出 \fIpattern\fRs 並且未給出 -\fBclear\fR標誌,這個命令返回這個名字空間當前的匯出列表。 .TP \fBnamespace forget \fR?\fIpattern pattern ...\fR? 刪除以前從一個名字空間匯入的命令。所有 \fIpattern\fR 都是一個限定的命令如 \fBfoo::x\fR 或 \fBa::b::p*\fR。限定的名字包含 \fB::\fR並且用一個或多個名字空間的名字限制一個名字。每個 \fIpattern\fR 被一個匯出名字空間的名字所限制,並且在限定的名字的結束處可以有萬用字元式樣的特殊字元。通配字元可以不出現在名字空間的名字中。這個命令首先查詢匹配的匯出命令。接著檢查是否有些命令是以前由當前名字空間匯入的。如果有,這個命令刪除相應的匯入的命令。效果上,這個命令撤消 \fBnamespace import\fR命令的動作。 .TP \fBnamespace import \fR?\fB\-force\fR? ?\fIpattern\fR \fIpattern ...\fR? 匯入命令到一個名字空間中。所有 \fIpattern\fR都是一個限定的命令如\fBfoo::x\fR 或 \fBa::p*\fR。就是說,它包括一個匯出名字空間的名字,並且在限定的名字的結束處可以有萬用字元式樣的特殊字元。通配字元可以不出現在名字空間的名字中。把所有匹配某個 \fIpattern\fR 字串並且被它們的名字空間匯出的命令新增到當前名字空間中。這是透過在當前名字空間中建立一個新命令,這個新命令指向在它的原始名字空間中的匯出命令;當呼叫這個新匯入的命令的時候,它呼叫那個匯出的命令。如果一個匯入的命令與一個現存的命令有衝突,則這個命令通常返回一個錯誤。但是,如果給出了 -\fBforce\fR 選項,在則匯入命令將悄無聲息的替換現存的命令。\fBnamespace import\fR 命令有當前快照(snapshot)語義: 就是說,在要求(匯入)的命令中,只匯入在匯出的名字空間中定義了的那些命令。換句話說,你只能匯入在執行 \fBnamespace import\fR 的時候在一個名字空間中(已經存在)的命令。如果此後又定義並匯出了其他命令,則不會匯入它們。 .TP \fBnamespace inscope\fR \fInamespace arg\fR ?\fIarg ...\fR? 在一個特定的名字空間的上下文中執行一個指令碼。不希望程式設計者直接執行這個命令;例如,在應用使用 \fBnamespace code\fR命令建立回撥指令碼,並且應用接著要向 Tk元件註冊它的時候,隱式的生成對它的呼叫。除了有 \fBlappend\fR語義並且名字空間必須已經存在之外,\fBnamespace inscope\fR命令與 \fBnamespace eval\fR 命令非常相似。它把第一個引數作為一個列表來對待,接著把後面的所有引數作為適當的列表元素新增到第一個引數的尾部。\fBnamespace inscope ::foo a x y z\fR 等價於\fBnamespace eval ::foo [concat a [list x y z]]\fR。這個 \fBlappend>\fR語義很重要,因為許多回調 指令碼實際上是字首。 .TP \fBnamespace origin \fIcommand\fR 返回匯入的命令 \fIcommand\fR所引用的原始命令的完全限定的名字。當一個命令被匯入一個名字空間的時候,在這個名字空間中建立一個新命令,它指向在匯出名字空間中的實際命令。如果一個命令被匯入到一個名字空間的序列 \fIa, b,...,n \fR之中,這裡每一個後續的名字空間只從前面的名字空間中匯入命令,這個命令返回在第一個名字空間中的原始命令的完全限定的名字 \fIa\fR。如果 \fIcommand\fR不引用一個匯入的命令,返回這個(\fIcommand\fR)命令自己的完全限定的名字。 .TP \fBnamespace parent\fR ?\fInamespace\fR? 返回給名字空間 \fInamespace\fR 的父名字空間的完全限定的名字。如果未指定 \fInamespace\fR,返回當前名字空間的父名字空間的完全限定的命令。 .TP \fBnamespace qualifiers\fR \fIstring\fR 返回給 \fIstring \fR的所有前導的名字空間限定符。限定符是由 \fB::\fR分隔的名字空間的名字。對於 \fIstring\fR \fB::foo::bar::x\fR,這個命令返回 \fB::foo::bar\fR,而對於 \fB::\fR它返回一個空串。這個命令與 \fBnamespace tail\fR 命令互補。注意,它不檢查名字空間的名字事實上是否是目前定義的名字空間的名字。 .TP \fBnamespace tail\fR \fIstring\fR 返回在一個限定的字串尾部的簡單名字。限定符是由 \fB::\fR分隔的名字空間的名字。對於 \fIstring\fR \fB::foo::bar::x\fR,這個命令返回 \fBx\fR,而對於 \fB::\fR它返回一個空串。這個命令與 \fBnamespace qualifiers\fR命令互補。它不檢查名字空間的名字事實上是否是目前定義的名字空間的名字。 .TP \fBnamespace which\fR ?\-\fBcommand\fR? ?\-\fBvariable\fR? \fIname\fR 把 \fIname\fR 作為一個命令或者變數來查詢並返回它的完全限定的名字。例如,如果 \fIname\fR 在當前名字空間中不存在但在全域性名字空間中存在,這個命令返回在全域性名字空間中的一個完全限定的名字。如果這個命令或變數不存在,這個命令返回空串。如果變數已經建立但未被定義,比如透過 \fBvariable\fR 命令或透過在變數上\fBtrace\fR(進行追蹤),這個命令返回這個變數的完全限定的名字。如果未給出標誌,\fIname\fR被作為一個命令的名字。關於名字解析的規則的解釋請參見下面的\fBNAME RESOLUTION\fR (名字解析)章節。 .SH "什麼名字空間 WHAT IS A NAMESPACE?" .PP 一個名字空間是命令和變數的一個集合(collection)。它封裝命令和變數來確保它們不會被其他名字空間中命令和變數所幹擾。Tcl 總是有一個這樣的集合,它被引用為\fIglobal namespace\fR (全域性名字空間)。全域性名字空間持有所有全域性變數和命令。\fBnamespace eval\fR命令讓你建立一個新的名字空間。例如, .CS \fBnamespace eval Counter { namespace export bump variable num 0 proc bump {} { variable num incr num } }\fR .CE 建立包含變數 \fBnum\fR 和過程 \fBbump \fR的一個新的名字空間。在這個名字空間中的命令和變數獨立於在同一個程式中的其他命令和變數。例如,如果在全域性名字空間中有一個叫 \fBbump\fR的命令,它不同的於在 \fBCounter\fR 名字空間中的 \fBbump\fR 命令。 .PP 名字空間變數類似於在 Tcl 中的全域性變數。它們存在於名字空間中的過程之外,但象在上面的例子中展示的那樣,在同一個名字空間中的過程可以透過 \fBvariable\fR 命令訪問它。 .PP 名字空間是動態的。你可以在任意時候增加及刪除命令和變數,所以你可以使用一系列 \fBnamespace eval\fR命令分幾次(over time)來建造一個名字空間的內容。例如,下面的一系列命令與上面展示的定義有相同的效果: .CS \fBnamespace 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 "" }\fR .CE 注意在例子中向 \fBCounter\fR 名字空間增加了 \fBtest\fR 過程,後來又用 \fBrename\fR命令把它刪除了。 .PP 在名字空間內可以又其他的名字空間,它們是有層次的巢狀。一個巢狀的名字空間被封裝在它的父名字空間中並且不會被其他名字空間所幹擾。 .SH "限定的名字 QUALIFIED NAMES" .PP 每個名字空間都有一個文字名字比如\fBhistory\fR 或 \fB::safe::interp\fR。因為名字空間可以巢狀,使用限定的名字來引用在名字空間中的命令、變數、和包含子名字空間。除了使用 \fB::\fR作為分隔符而不是 \fB/\fR 或 \fB.\fR 之外,限定的(qualified)名字類似於給 Unix 檔案或 Tk 元件的有層次的路徑,最頂層或全域性名字空間擁有名字“” (一個空串),而 \fB::\fR 是它的同義詞。例如,名字 \fB::safe::interp::create\fR 引用在名字空間 \fB::safe \fR的子名字空間 \fBinterp\fR 中的命令 \fBcreate\fR,\fB::safe \fR是全域性名字空間 \fB:: \fR的子名字空間。 .PP 如果你打算從其他的名字空間中訪問命令和變數,你必須使用額外的語法。名字必須被包含它們的名字空間所限定。例如我們可以象下面這樣訪問 \fBCounter\fR 的過程: .CS \fBCounter::bump 5 Counter::Reset\fR .CE 我們可以象下面這樣訪問當前的 count (變數的值): .CS \fBputs "count = $Counter::num"\fR .CE 當一個名字空間包含另一個的時候,要到達它的元素你可能需要多於一個的限定符。如果我們有一個名字空間 \fBFoo\fR,它包含名字空間 \fBCounter\fR,你可以象下面這樣從全域性名字空間呼叫它的 \fBbump\fR 過程: .CS \fBFoo::Counter::bump 3\fR .CE .PP 你還可以在建立和重新命名命令的時候使用限定的名字。例如,你可以象下面這樣向 \fBFoo\fR增加一個過程: .CS \fBproc Foo::Test {args} {return $args}\fR .CE 你可以象下面這樣把同一個過程移動到另一個名字空間中: .CS \fBrename Foo::Test Bar::Test\fR .CE .PP 我們覆蓋(cover)剩下的一些關於限定的名字的要點。除了全域性名字空間之外名字空間有非空的名字。除了作為名字空間分隔符,不允許 \fB::\fR 在簡單命令、變數、和名字空間名字中使用。在限定的名字中忽略額外的 \fB:\fR ;就是說,兩個或更多的 \fB: \fR被作為一個名字空間分隔符。在一個限定的變數或命令名字中的尾隨的 \fB::\fR 引用叫做 {} 的變數或命令。但是忽略在一個限定的名字空間名中的尾隨的 \fB::\fR。 .SH NAME .PP 一般的,所有接受變數和命令的名字的 Tcl 命令都支援限定的名字。這意味著你可以把限定的名字給這樣的命令如\fBset\fR、\fBproc\fR、\fBrename\fR、和 \fBinterp alias\fR。如果你提供了以 \fB:: \fR開始的一個完全限定的名字,對任何命令、變數、或名字空間多沒有問題。但是,如果這個名字不以一個 \fB::\fR 開始(它是\fI相對的\fR),Tcl 依據一個固定的規則來查詢它: 解析命令和變數名字總是首先在當前的名字空間中查詢,接著在全域性名字空間中查詢。另一方面,解析名字空間總是在當前名字空間中查詢。 .PP 在下列例子中, .CS \fBset traceLevel 0 namespace eval Debug { printTrace $traceLevel }\fR .CE Tcl 在名字空間 \fBDebug\fR 中查詢 \fBtraceLevel\fR接著在全域性名字空間中查詢,它以相同的方式查詢命令 \fBprintTrace\fR。如果一個變數或命令的名字在這兩個上下文中都找不到,則這個名字是未定義的。為了使這一點絕對清楚,考慮下列例子: .CS \fBset traceLevel 0 namespace eval Foo { variable traceLevel 3 namespace eval Debug { printTrace $traceLevel } }\fR .CE 這裡 Tcl 首先在名字空間 \fBFoo::Debug \fR中查詢 \fBtraceLevel\fR。因為在這裡未找到,Tcl 接著在全域性名字空間中查詢。在名字解析過程中完全忽略了變數 \fBFoo::traceLevel\fR。 .PP 你可以使用 \fBnamespace which\fR 命令來清除關於名字解析的任何問題: .CS \fBnamespace eval Foo::Debug {namespace which \-variable traceLevel}\fR .CE 返回 \fB::traceLevel\fR。另一方面,命令, .CS \fBnamespace eval Foo {namespace which \-variable traceLevel}\fR .CE 返回 \fB::Foo::traceLevel\fR. .PP 如上面提及的那樣,查詢名字空間名字與變數和命令的名字不同。總是在當前名字空間中解析名字空間名字。這意味除非新名字空間的名字以一個 \fB::\fR開始,否則建立一個新名字空間的 \fBnamespace eval\fR 命令總是建立當前名字空間的一個子名字空間。 .PP Tcl 對你可以引用的變數、命令、或名字空間沒有訪問控制。如果你能提供一個限定的名字來透過名字解析規則解析到一個元素,你就可以訪問這個元素。 .PP 你可以透過 \fBvariable\fR 命令從同一個名字空間中的一個過程中訪問一個名字空間變數。非常象 \fBglobal\fR 命令,它建立到名字空間變數的一個本地連線。如果需要,這個命令還在當前的名字空間中建立這個變數並初始化它。注意:\fBglobal\fR命令只建立到在全域性名字空間中的變數的連線。如果你總是使用一個適當的限定的名字來引用名字空間變數,則使用 \fBvariable\fR 命令不是必須的。 .SH "匯入命令 IMPORTING COMMANDS" .PP 名字空間經常用來表示庫。一些庫命令使用的如此頻繁以至於鍵入它們的限定的名字是極其煩人的。例如, 假設在一個包如 BLT 中的所有命令都包含在一個叫 \fBBlt \fR的名字空間中。則你可以象下面這樣訪問這些命令: .CS \fBBlt::graph .g \-background red Blt::table . .g 0,0\fR .CE 如果你頻繁使用 \fBgraph\fR 和 \fBtable\fR 命令,你可能希望訪問它們而不用加 \fBBlt::\fR字首。你可以透過把它匯入到當前名字空間中的方式來達到此目的。例如: .CS \fBnamespace import Blt::*\fR .CE 這個例子把從 \fBBlt\fR名字空間匯出的所有命令增加到當前名字空間上下文中,所以你可以象下面這樣寫程式碼: .CS \fBgraph .g \-background red table . .g 0,0\fR .CE \fBnamespace import\fR命令從一個名字空間匯入的命令只能是那個名字空間中用 \fBnamespace export\fR命令匯出的命令。 .PP 從一個名字空間匯入\fI所有\fR命令一般是一個壞主意,因為你不知道你將會得到些什麼。更好的方式是隻匯入你需要的命令。例如,命令 .CS \fBnamespace import Blt::graph Blt::table\fR .CE 只把 \fBgraph\fR 和 \fBtable\fR 命令匯入到當前上下文。 .PP 如果你要匯入一個已經存在的命令,你將得到一個錯誤。這防止你從兩個不同的包匯入同一個命令。但是有的時候(可能在除錯時),你可能希望超越這個限制。你可能希望重新發起(reissue) \fBnamespace import\fR命令來匯入(pick up)一個新命令,而同名的命令在這個名字空間中已經出現過了。在這種情況下,你可以使用 \fB-force\fR 選項,現存命令將悄無聲息的被覆寫(overwritten): .CS \fBnamespace import \-force Blt::graph Blt::table\fR .CE 如果出於某種原因,你打算停止使用匯入的命令,你可以用 \fBnamespace forget\fR 命令刪除它們,例如: .CS \fBnamespace forget Blt::*\fR .CE 它在當前名子空間中查詢從 \fBBlt \fR匯入的所有命令,如果找到則刪除它們。否則,它什麼都不做。此後,訪問 \fBBlt\fR命令必須使用 \fBBlt::\fR 字首。 .PP 當你從匯出(命令的)名字空間刪除一個命令的時候,例如: .CS \fBrename Blt::graph ""\fR .CE 則從所有匯入它的名字空間中自動刪除這個命令。 .SH "匯出命令 EXPORTING COMMANDS" 你可以從一個名字空間中匯出命令,例如: .CS \fBnamespace 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!" } } }\fR .CE 過程 \fBbump\fR 和 \fBreset\fR 被匯出,所以當你從 \fBCounter\fR 名字空間匯入的時候,它們被包括在內。例如: .CS \fBnamespace import Counter::*\fR .CE 但是 \fBCheck\fR 過程未被匯出,所以它被匯入操作所忽略。 .PP \fBnamespace import\fR,命令只匯入被它們的名字空間匯出的命令。\fBnamespace export\fR 命令指定什麼命令可以被其他名字空間匯入。如果一個 \fBnamespace import\fR命令指定了一個未被匯出的命令,則不匯入這個命令。 .SH "參見 SEE ALSO" variable(n) .SH "關鍵字 KEYWORDS" exported, internal, variable .SH "[中文版維護人]" .B 寒蟬退士 .SH "[中文版最新更新]" .B 2001/10/12 .SH "《中國 Linux 論壇 man 手冊頁翻譯計劃》:" .BI http://cmpp.linuxforum.net .SH "跋" .br 本頁面中文版由中文 man 手冊頁計劃提供。 .br 中文 man 手冊頁計劃:\fBhttps://github.com/man-pages-zh/manpages-zh\fR