namespace.n
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:23k
- '"
- '" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
- '" Copyright (c) 1997 Sun Microsystems, Inc.
- '" Copyright (c) 2000 Scriptics Corporation.
- '"
- '" 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.9.2.2 2005/05/12 16:23:11 dgp Exp $
- '"
- .so man.macros
- .TH namespace n 8.0 Tcl "Tcl Built-In Commands"
- .BS
- '" Note: do not modify the .SH NAME line immediately below!
- .SH NAME
- namespace - create and manipulate contexts for commands and variables
- .SH SYNOPSIS
- fBnamespace fR?fIoptionfR? ?fIarg ...fR?
- .BE
- .SH DESCRIPTION
- .PP
- The fBnamespacefR command lets you create, access, and destroy
- separate contexts for commands and variables.
- See the section fBWHAT IS A NAMESPACE?fR below
- for a brief overview of namespaces.
- The legal values of fIoptionfR are listed below.
- Note that you can abbreviate the fIoptionfRs.
- .TP
- fBnamespace children fR?fInamespacefR? ?fIpatternfR?
- Returns a list of all child namespaces that belong to the
- namespace fInamespacefR.
- If fInamespacefR is not specified,
- then the children are returned for the current namespace.
- This command returns fully-qualified names,
- which start with a double colon (fB::fR).
- If the optional fIpatternfR is given,
- then this command returns only the names that match the glob-style pattern.
- The actual pattern used is determined as follows:
- a pattern that starts with double colon (fB::fR) is used directly,
- otherwise the namespace fInamespacefR
- (or the fully-qualified name of the current namespace)
- is prepended onto the pattern.
- .TP
- fBnamespace code fIscriptfR
- Captures the current namespace context for later execution
- of the script fIscriptfR.
- It returns a new script in which fIscriptfR has been wrapped
- in a fBnamespace inscopefR command.
- The new script has two important properties.
- First, it can be evaluated in any namespace and will cause
- fIscriptfR to be evaluated in the current namespace
- (the one where the fBnamespace codefR command was invoked).
- Second, additional arguments can be appended to the resulting script
- and they will be passed to fIscriptfR as additional arguments.
- For example, suppose the command
- fBset script [namespace code {foo bar}]fR
- is invoked in namespace fB::a::bfR.
- Then fBeval "$script x y"fR
- can be executed in any namespace (assuming the value of
- fBscriptfR has been passed in properly)
- and will have the same effect as the command
- fB::namespace eval ::a::b {foo bar x y}fR.
- This command is needed because
- extensions like Tk normally execute callback scripts
- in the global namespace.
- A scoped command captures a command together with its namespace context
- in a way that allows it to be executed properly later.
- See the section fBSCOPED SCRIPTSfR for some examples
- of how this is used to create callback scripts.
- .TP
- fBnamespace currentfR
- Returns the fully-qualified name for the current namespace.
- The actual name of the global namespace is ``''
- (i.e., an empty string),
- but this command returns fB::fR for the global namespace
- as a convenience to programmers.
- .TP
- fBnamespace delete fR?fInamespace namespace ...fR?
- Each namespace fInamespacefR is deleted
- and all variables, procedures, and child namespaces
- contained in the namespace are deleted.
- If a procedure is currently executing inside the namespace,
- the namespace will be kept alive until the procedure returns;
- however, the namespace is marked to prevent other code from
- looking it up by name.
- If a namespace doesn't exist, this command returns an error.
- If no namespace names are given, this command does nothing.
- .TP
- fBnamespace evalfR fInamespace argfR ?fIarg ...fR?
- Activates a namespace called fInamespacefR and evaluates some code
- in that context.
- If the namespace does not already exist, it is created.
- If more than one fIargfR argument is specified,
- the arguments are concatenated together with a space between each one
- in the same fashion as the fBevalfR command,
- and the result is evaluated.
- .br
- .sp
- If fInamespacefR has leading namespace qualifiers
- and any leading namespaces do not exist,
- they are automatically created.
- .TP
- fBnamespace existsfR fInamespacefR
- Returns fB1fR if fInamespacefR is a valid namespace in the current
- context, returns fB0fR otherwise.
- .TP
- fBnamespace export fR?-fBclearfR? ?fIpattern pattern ...fR?
- Specifies which commands are exported from a namespace.
- The exported commands are those that can be later imported
- into another namespace using a fBnamespace importfR command.
- Both commands defined in a namespace and
- commands the namespace has previously imported
- can be exported by a namespace.
- The commands do not have to be defined
- at the time the fBnamespace exportfR command is executed.
- Each fIpatternfR may contain glob-style special characters,
- but it may not include any namespace qualifiers.
- That is, the pattern can only specify commands
- in the current (exporting) namespace.
- Each fIpatternfR is appended onto the namespace's list of export patterns.
- If the -fBclearfR flag is given,
- the namespace's export pattern list is reset to empty before any
- fIpatternfR arguments are appended.
- If no fIpatternfRs are given and the -fBclearfR flag isn't given,
- this command returns the namespace's current export list.
- .TP
- fBnamespace forget fR?fIpattern pattern ...fR?
- Removes previously imported commands from a namespace.
- Each fIpatternfR is a simple or qualified name such as
- fBxfR, fBfoo::xfR or fBa::b::p*fR.
- Qualified names contain double colons (fB::fR) and qualify a name
- with the name of one or more namespaces.
- Each fIqualified patternfR is qualified with the name of an
- exporting namespace
- and may have glob-style special characters in the command name
- at the end of the qualified name.
- Glob characters may not appear in a namespace name.
- For each fIsimple patternfR this command deletes the matching
- commands of the
- current namespace that were imported from a different namespace.
- For fIqualified patternsfR, this command first finds the matching
- exported commands.
- It then checks whether any of those commands
- were previously imported by the current namespace.
- If so, this command deletes the corresponding imported commands.
- In effect, this un-does the action of a fBnamespace importfR command.
- .TP
- fBnamespace import fR?fB-forcefR? ?fIpatternfR fIpattern ...fR?
- Imports commands into a namespace.
- Each fIpatternfR is a qualified name like
- fBfoo::xfR or fBa::p*fR.
- That is, it includes the name of an exporting namespace
- and may have glob-style special characters in the command name
- at the end of the qualified name.
- Glob characters may not appear in a namespace name.
- All the commands that match a fIpatternfR string
- and which are currently exported from their namespace
- are added to the current namespace.
- This is done by creating a new command in the current namespace
- that points to the exported command in its original namespace;
- when the new imported command is called, it invokes the exported command.
- This command normally returns an error
- if an imported command conflicts with an existing command.
- However, if the -fBforcefR option is given,
- imported commands will silently replace existing commands.
- The fBnamespace importfR command has snapshot semantics:
- that is, only requested commands that are currently defined
- in the exporting namespace are imported.
- In other words, you can import only the commands that are in a namespace
- at the time when the fBnamespace importfR command is executed.
- If another command is defined and exported in this namespace later on,
- it will not be imported.
- .TP
- fBnamespace inscopefR fInamespacefR fIscriptfR ?fIarg ...fR?
- Executes a script in the context of the specified fInamespacefR.
- This command is not expected to be used directly by programmers;
- calls to it are generated implicitly when applications
- use fBnamespace codefR commands to create callback scripts
- that the applications then register with, e.g., Tk widgets.
- The fBnamespace inscopefR command is much like the fBnamespace evalfR
- command except that the fInamespacefR must already exist,
- and fBnamespace inscopefR appends additional fIargfRs
- as proper list elements.
- .br
- fBnamespace inscope ::foo $script $x $y $zfR
- is equivalent to
- fBnamespace eval ::foo [concat $script [list $x $y $z]]fR
- thus additional arguments will not undergo a second round of substitution,
- as is the case with fBnamespace evalfR.
- .TP
- fBnamespace origin fIcommandfR
- Returns the fully-qualified name of the original command
- to which the imported command fIcommandfR refers.
- When a command is imported into a namespace,
- a new command is created in that namespace
- that points to the actual command in the exporting namespace.
- If a command is imported into a sequence of namespaces
- fIa, b,...,nfR where each successive namespace
- just imports the command from the previous namespace,
- this command returns the fully-qualified name of the original command
- in the first namespace, fIafR.
- If fIcommandfR does not refer to an imported command,
- the command's own fully-qualified name is returned.
- .TP
- fBnamespace parentfR ?fInamespacefR?
- Returns the fully-qualified name of the parent namespace
- for namespace fInamespacefR.
- If fInamespacefR is not specified,
- the fully-qualified name of the current namespace's parent is returned.
- .TP
- fBnamespace qualifiersfR fIstringfR
- Returns any leading namespace qualifiers for fIstringfR.
- Qualifiers are namespace names separated by double colons (fB::fR).
- For the fIstringfR fB::foo::bar::xfR,
- this command returns fB::foo::barfR,
- and for fB::fR it returns an empty string.
- This command is the complement of the fBnamespace tailfR command.
- Note that it does not check whether the
- namespace names are, in fact,
- the names of currently defined namespaces.
- .TP
- fBnamespace tailfR fIstringfR
- Returns the simple name at the end of a qualified string.
- Qualifiers are namespace names separated by double colons (fB::fR).
- For the fIstringfR fB::foo::bar::xfR,
- this command returns fBxfR,
- and for fB::fR it returns an empty string.
- This command is the complement of the fBnamespace qualifiersfR command.
- It does not check whether the namespace names are, in fact,
- the names of currently defined namespaces.
- .TP
- fBnamespace whichfR ?-fBcommandfR? ?-fBvariablefR? fInamefR
- Looks up fInamefR as either a command or variable
- and returns its fully-qualified name.
- For example, if fInamefR does not exist in the current namespace
- but does exist in the global namespace,
- this command returns a fully-qualified name in the global namespace.
- If the command or variable does not exist,
- this command returns an empty string. If the variable has been
- created but not defined, such as with the fBvariablefR command
- or through a fBtracefR on the variable, this command will return the
- fully-qualified name of the variable.
- If no flag is given, fInamefR is treated as a command name.
- See the section fBNAME RESOLUTIONfR below for an explanation of
- the rules regarding name resolution.
- .SH "WHAT IS A NAMESPACE?"
- .PP
- A namespace is a collection of commands and variables.
- It encapsulates the commands and variables to ensure that they
- won't interfere with the commands and variables of other namespaces.
- Tcl has always had one such collection,
- which we refer to as the fIglobal namespacefR.
- The global namespace holds all global variables and commands.
- The fBnamespace evalfR command lets you create new namespaces.
- For example,
- .CS
- fBnamespace evalfR Counter {
- fBnamespace exportfR bump
- variable num 0
- proc bump {} {
- variable num
- incr num
- }
- }
- .CE
- creates a new namespace containing the variable fBnumfR and
- the procedure fBbumpfR.
- The commands and variables in this namespace are separate from
- other commands and variables in the same program.
- If there is a command named fBbumpfR in the global namespace,
- for example, it will be different from the command fBbumpfR
- in the fBCounterfR namespace.
- .PP
- Namespace variables resemble global variables in Tcl.
- They exist outside of the procedures in a namespace
- but can be accessed in a procedure via the fBvariablefR command,
- as shown in the example above.
- .PP
- Namespaces are dynamic.
- You can add and delete commands and variables at any time,
- so you can build up the contents of a
- namespace over time using a series of fBnamespace evalfR commands.
- For example, the following series of commands has the same effect
- as the namespace definition shown above:
- .CS
- fBnamespace evalfR Counter {
- variable num 0
- proc bump {} {
- variable num
- return [incr num]
- }
- }
- fBnamespace evalfR Counter {
- proc test {args} {
- return $args
- }
- }
- fBnamespace evalfR Counter {
- rename test ""
- }
- .CE
- Note that the fBtestfR procedure is added to the fBCounterfR namespace,
- and later removed via the fBrenamefR command.
- .PP
- Namespaces can have other namespaces within them,
- so they nest hierarchically.
- A nested namespace is encapsulated inside its parent namespace
- and can not interfere with other namespaces.
- .SH "QUALIFIED NAMES"
- .PP
- Each namespace has a textual name such as
- fBhistoryfR or fB::safe::interpfR.
- Since namespaces may nest,
- qualified names are used to refer to
- commands, variables, and child namespaces contained inside namespaces.
- Qualified names are similar to the hierarchical path names for
- Unix files or Tk widgets,
- except that fB::fR is used as the separator
- instead of fB/fR or fB.fR.
- The topmost or global namespace has the name ``'' (i.e., an empty string),
- although fB::fR is a synonym.
- As an example, the name fB::safe::interp::createfR
- refers to the command fBcreatefR in the namespace fBinterpfR
- that is a child of namespace fB::safefR,
- which in turn is a child of the global namespace, fB::fR.
- .PP
- If you want to access commands and variables from another namespace,
- you must use some extra syntax.
- Names must be qualified by the namespace that contains them.
- From the global namespace,
- we might access the fBCounterfR procedures like this:
- .CS
- Counter::bump 5
- Counter::Reset
- .CE
- We could access the current count like this:
- .CS
- puts "count = $Counter::num"
- .CE
- When one namespace contains another, you may need more than one
- qualifier to reach its elements.
- If we had a namespace fBFoofR that contained the namespace fBCounterfR,
- you could invoke its fBbumpfR procedure
- from the global namespace like this:
- .CS
- Foo::Counter::bump 3
- .CE
- .PP
- You can also use qualified names when you create and rename commands.
- For example, you could add a procedure to the fBFoofR
- namespace like this:
- .CS
- proc Foo::Test {args} {return $args}
- .CE
- And you could move the same procedure to another namespace like this:
- .CS
- rename Foo::Test Bar::Test
- .CE
- .PP
- There are a few remaining points about qualified names
- that we should cover.
- Namespaces have nonempty names except for the global namespace.
- fB::fR is disallowed in simple command, variable, and namespace names
- except as a namespace separator.
- Extra colons in any separator part of a qualified name are ignored;
- i.e. two or more colons are treated as a namespace separator.
- A trailing fB::fR in a qualified variable or command name
- refers to the variable or command named {}.
- However, a trailing fB::fR in a qualified namespace name is ignored.
- .SH "NAME RESOLUTION"
- .PP
- In general, all Tcl commands that take variable and command names
- support qualified names.
- This means you can give qualified names to such commands as
- fBsetfR, fBprocfR, fBrenamefR, and fBinterp aliasfR.
- If you provide a fully-qualified name that starts with a fB::fR,
- there is no question about what command, variable, or namespace
- you mean.
- However, if the name does not start with a fB::fR
- (i.e., is fIrelativefR),
- Tcl follows a fixed rule for looking it up:
- Command and variable names are always resolved
- by looking first in the current namespace,
- and then in the global namespace.
- Namespace names, on the other hand, are always resolved
- by looking in only the current namespace.
- .PP
- In the following example,
- .CS
- set traceLevel 0
- fBnamespace evalfR Debug {
- printTrace $traceLevel
- }
- .CE
- Tcl looks for fBtraceLevelfR in the namespace fBDebugfR
- and then in the global namespace.
- It looks up the command fBprintTracefR in the same way.
- If a variable or command name is not found in either context,
- the name is undefined.
- To make this point absolutely clear, consider the following example:
- .CS
- set traceLevel 0
- fBnamespace evalfR Foo {
- variable traceLevel 3
- fBnamespace evalfR Debug {
- printTrace $traceLevel
- }
- }
- .CE
- Here Tcl looks for fBtraceLevelfR first in the namespace fBFoo::DebugfR.
- Since it is not found there, Tcl then looks for it
- in the global namespace.
- The variable fBFoo::traceLevelfR is completely ignored
- during the name resolution process.
- .PP
- You can use the fBnamespace whichfR command to clear up any question
- about name resolution.
- For example, the command:
- .CS
- fBnamespace evalfR Foo::Debug {fBnamespace whichfR -variable traceLevel}
- .CE
- returns fB::traceLevelfR.
- On the other hand, the command,
- .CS
- fBnamespace evalfR Foo {fBnamespace whichfR -variable traceLevel}
- .CE
- returns fB::Foo::traceLevelfR.
- .PP
- As mentioned above,
- namespace names are looked up differently
- than the names of variables and commands.
- Namespace names are always resolved in the current namespace.
- This means, for example,
- that a fBnamespace evalfR command that creates a new namespace
- always creates a child of the current namespace
- unless the new namespace name begins with fB::fR.
- .PP
- Tcl has no access control to limit what variables, commands,
- or namespaces you can reference.
- If you provide a qualified name that resolves to an element
- by the name resolution rule above,
- you can access the element.
- .PP
- You can access a namespace variable
- from a procedure in the same namespace
- by using the fBvariablefR command.
- Much like the fBglobalfR command,
- this creates a local link to the namespace variable.
- If necessary, it also creates the variable in the current namespace
- and initializes it.
- Note that the fBglobalfR command only creates links
- to variables in the global namespace.
- It is not necessary to use a fBvariablefR command
- if you always refer to the namespace variable using an
- appropriate qualified name.
- .SH "IMPORTING COMMANDS"
- .PP
- Namespaces are often used to represent libraries.
- Some library commands are used so frequently
- that it is a nuisance to type their qualified names.
- For example, suppose that all of the commands in a package
- like BLT are contained in a namespace called fBBltfR.
- Then you might access these commands like this:
- .CS
- Blt::graph .g -background red
- Blt::table . .g 0,0
- .CE
- If you use the fBgraphfR and fBtablefR commands frequently,
- you may want to access them without the fBBlt::fR prefix.
- You can do this by importing the commands into the current namespace,
- like this:
- .CS
- fBnamespace importfR Blt::*
- .CE
- This adds all exported commands from the fBBltfR namespace
- into the current namespace context, so you can write code like this:
- .CS
- graph .g -background red
- table . .g 0,0
- .CE
- The fBnamespace importfR command only imports commands
- from a namespace that that namespace exported
- with a fBnamespace exportfR command.
- .PP
- Importing fIeveryfR command from a namespace is generally
- a bad idea since you don't know what you will get.
- It is better to import just the specific commands you need.
- For example, the command
- .CS
- fBnamespace importfR Blt::graph Blt::table
- .CE
- imports only the fBgraphfR and fBtablefR commands into the
- current context.
- .PP
- If you try to import a command that already exists, you will get an
- error. This prevents you from importing the same command from two
- different packages. But from time to time (perhaps when debugging),
- you may want to get around this restriction. You may want to
- reissue the fBnamespace importfR command to pick up new commands
- that have appeared in a namespace. In that case, you can use the
- fB-forcefR option, and existing commands will be silently overwritten:
- .CS
- fBnamespace importfR -force Blt::graph Blt::table
- .CE
- If for some reason, you want to stop using the imported commands,
- you can remove them with a fBnamespace forgetfR command, like this:
- .CS
- fBnamespace forgetfR Blt::*
- .CE
- This searches the current namespace for any commands imported from fBBltfR.
- If it finds any, it removes them. Otherwise, it does nothing.
- After this, the fBBltfR commands must be accessed with the fBBlt::fR
- prefix.
- .PP
- When you delete a command from the exporting namespace like this:
- .CS
- rename Blt::graph ""
- .CE
- the command is automatically removed from all namespaces that import it.
- .SH "EXPORTING COMMANDS"
- You can export commands from a namespace like this:
- .CS
- fBnamespace evalfR Counter {
- fBnamespace exportfR 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!"
- }
- }
- }
- .CE
- The procedures fBbumpfR and fBresetfR are exported,
- so they are included when you import from the fBCounterfR namespace,
- like this:
- .CS
- fBnamespace importfR Counter::*
- .CE
- However, the fBCheckfR procedure is not exported,
- so it is ignored by the import operation.
- .PP
- The fBnamespace importfR command only imports commands
- that were declared as exported by their namespace.
- The fBnamespace exportfR command specifies what commands
- may be imported by other namespaces.
- If a fBnamespace importfR command specifies a command
- that is not exported, the command is not imported.
- .SH "SCOPED SCRIPTS"
- The fBnamespace codefR command is the means by which a script may be
- packaged for evaluation in a namespace other than the one in which it
- was created. It is used most often to create event handlers, Tk bindings,
- and traces for evaluation in the global context. For instance, the following
- code indicates how to direct a variable trace callback into the current
- namespace:
- .CS
- fBnamespace evalfR a {
- variable b
- proc theTraceCallback { n1 n2 op } {
- upvar 1 $n1 var
- puts "the value of $n1 has changed to $var"
- return
- }
- trace variable b w [fBnamespace codefR theTraceCallback]
- }
- set a::b c
- .CE
- When executed, it prints the message:
- .CS
- the value of a::b has changed to c
- .CE
- .SH EXAMPLES
- Create a namespace containing a variable and an exported command:
- .CS
- fBnamespace evalfR foo {
- variable bar 0
- proc grill {} {
- variable bar
- puts "called [incr bar] times"
- }
- fBnamespace exportfR grill
- }
- .CE
- .PP
- Call the command defined in the previous example in various ways.
- .CS
- # Direct call
- foo::grill
- # Import into current namespace, then call local alias
- namespace import foo::grill
- grill
- .CE
- .PP
- Look up where the command imported in the previous example came from:
- .CS
- puts "grill came from [fBnamespace originfR grill]"
- .CE
- .SH "SEE ALSO"
- variable(n)
- .SH KEYWORDS
- exported, internal, variable