Namespace (computer science)
|
Many modern computer languages provide support for namespaces.
A namespace is a context for identifiers. An identifier defined in a namespace is associated with that namespace. An identifier can be defined in multiple namespaces. The meaning of an identifier in one namespace is completely separate from the meaning it has in any other namespace. Thus, a namespace introduces a new domain in which one can define any identifier with the guarantee that it will not clash with existing identifiers (because those will be associated with other namespaces).
For example, Bill works for company X and his employee ID is 123. John works for company Y and his employee ID is also 123. The reason Bill and John can be identified by the same ID number is because they work for different companies. The different companies in this case would symbolize different namespaces. If the two men worked for the same company, and still had the same employee ID, there may be serious errors when it comes time to pay them.
This characteristic is the primary motivation for the use of namespaces. In large computer programs or documents it is not uncommon to have hundreds or thousands of identifiers. Without namespaces (or a similar technique, see Emulating namespaces) it is hard to ensure uniqueness of identifiers in these cases. Namespaces provide an easy means to group logically related identifiers into corresponding namespaces, thereby making the system more modular.
In programming languages, namespaces are scopes that use the enclosing nature of the scope to group logically related identifiers under a single identifier. In some programming languages (eg. C++, Python), these identifiers naming namespaces are themselves associated with an enclosing namespace. Thus, in these languages namespaces can nest, forming a namespace tree. At the root of this tree is the unnamed global namespace.
Function and class scopes can be viewed as implicit namespaces which are inextricably linked with visibility, accessibility, and object lifetime.
Contents |
Use in common languages
In C++, a namespace is defined with a namespace block.
namespace foo { int bar; }
Within this block, identifiers can be used exactly as they are declared. Outside of this block, the namespace specifier must be prefixed. For example, outside of namespace foo
, bar
must be written foo::bar
. C++ includes another construct which makes this verbosity unnecessary. By adding the line
using namespace foo;
to a piece of code, the prefix foo::
is no longer needed.
Code that is not explicitly declared within a namespace is considered to be in the default namespace.
Namespaces in C++ are hierarchical. Within the hypothetical namespace food::fruit
, the identifier orange
refers to food::fruit::orange
if it exists, or if not food::orange
if it exists. If neither exist, orange
refers to an identifier in the default namespace.
Namespaces in C++ are most often used to avoid naming collisions. Although namespaces are used extensively in recent C++ code, most older code does not use this facility. For example, the entire standard library is defined within namespace std
, and in earlier standards of the language, in the default namespace.
In Java, the idea of a namespace is embodied in packages. All code belongs to a package, although that package need not be explicitly named. Code from other packages is accessed by prefixing the package name before the appropriate identifier, for example class String
in package java.lang
can be referred to as java.lang.String
(this is known as the fully qualified class name). Like C++, Java offers a construct which makes it unnecessary to type the package name (import
). However, certain features (such as reflection) require the programmer to use the fully qualified name.
Unlike C++, namespaces in Java are not hierarchical as far as the syntax of the language is concerned. However, packages are named in a hierarchical manner. For example, all packages beginning with java
are a part of the Java platform, the package java.lang
contains classes core to the language, and java.lang.reflect
contains core classes specifically relating to reflection.
In Java (as well as Ada, C#, and others), namespaces/packages express semantic categories of code. For example, in C#, namespace System
contains code provided by the system (the .NET framework). How specific these categories are and how deep the hierarchies go differ from language to language.
Although it is not a programming language, XML makes extensive use of namespaces.
XML
An XML namespace is a W3C standard for providing uniquely named elements and attributes in an XML instance. An XML instance may contain element or attribute names from more than one XML vocabulary. If each vocabulary is given a namespace then the ambiguity between identically named elements or attributes can be resolved.
All element names within a namespace must be unique.
A simple example would be to consider an XML instance that contained references to a customer and an ordered product. Both the customer element and the product element could have a child element "ID_number". Refences to the element ID_number would therefore be ambiguous unless the two identically named but semantically different elements were brought under namespaces that would differentiate them.
A namespace is declared using the reserved XML attribute xmlns
, the value of which must be a URI (Uniform Resource Identifier) reference e.g. xmlns="http://www.w3.org/1999/xhtml". The declaration can also include a short prefix with which elements and attributes can be identified e.g. xmlns:xhtml="http://www.w3.org/1999/xhtml".
An XML namespace does not require that its vocabulary be defined, though it is fairly common practice to place either a DTD or an XML Schema defining the precise data structure at the location of the namespace's URI.
Emulating namespaces
In programming languages that do not provide language support for namespaces, namespaces can be emulated to some extent by using an identifier naming convention. For example, C libraries such as Libpng often use a fixed prefix for all functions and variables that are part of their exposed interface. Libpng exposes identifiers such as:
png_create_write_struct png_get_signature png_read_row png_set_invalid
This gives reasonable assurance that the identifiers are unique and can therefore be used in larger programs without fear of identifier collisions.
Unfortunately, this technique has several drawbacks:
- It doesn't scale well to nested namespaces; identifiers become excessively long.
- In effect, all uses of the identifiers must be fully namespace-qualified. Languages with direct support for namespaces usually provide ways for the programmer to declare up front that they wish to use some or all identifiers from a specific namespace, which they can then use without qualification for the remainder of the block.
See also
External Links
- W3 XML Namespace documentation (http://www.w3.org/TR/REC-xml-names/)
- XML Namespace Tutorial (http://www.w3schools.com/xml/xml_namespaces.asp)