Namespaces
Namespaces are a light-weight feature to avoid name-clashes of objects. A namespace
is a special object which allows you to create your own object naming scope inside an
interpreter. Objects in a namespace can be accessed using the namespace qualifier name
followed by :: and the object name. When you nest objects using ::
automatically a namespace scope is created.
A namespace object is a way to manipulate and use namespaces
and namespace members.
For instance, if you create a namespace object N::O, an object at the
global level with the same name can be created, too, without a name-clash:
Namespace create N
Object create N::O
Object create O
N::O set x 1
Always accessing namespace objects, such as N::O in the example above, using the
fully qualified name (i.e., with ::) is tedious. Also, you cannot simply copy or load
code that you have written for the global scope into a namespace. This problem is tackled
by the method evalInScope. evalInScope allows you to define
namespace objects without qualifiers:
Namespace create N -evalInScope {
Object create O
}
N::O set x 1
Sometimes you might want to access a namespace object from within another namespace
scope. Of course, you can use the fully qualified names to access the
namespace objects. But sometimes it is easier to nest evalInScope invocations:
the objects from all surrounding namespaces (including the global namespace) are then
accessible, and new objects are created in the innermost namespace. For instance, the
following code creates a namespace M, and in M an instance of N::O is
created by nesting evalInScope calls. The fully qualified name of the new instance
is M::mo.
Namespace create M
N evalInScope {
M evalInScope {
O create mo
}
}
You can also define global objects with access to a namespace scope:
N evalGlobalInScope {
O create go
}
This code creates a global object go as instance of N::O.
If you are in a namespace scope, you can force an evaluation in the global namespace
by using Namespace evalGlobal. For instance, next we create a global object O2,
even though we are in N's namespace scope.
Namespace create N -evalInScope {
Namespace evalGlobal {
Object create O2
}
}
O2 set x 1
Finally, Namespace provides a number of methods for querying and manipulating
the namespace members, such as getMembers, isMember, etc. (explained below).
In this section, we provide a reference for all the methods provided by Namespace.
<namespaceID> evalGlobalInScope <code>
This methods enables you evaluate code globally, in a namespace scope.
That is, the objects in this namespace are accessible to the evaluated code,
but newly created objects are created in the global namespace. In other words,
this methods enables you to use the content of a namespace globally, without
using namespace qualifiers.
In the following code, we create Namespace N1 and an object b in it.
Using evalGlobalInScope we can access b without namespace qualifier, but
still the new code creates global objects. That is, a global object a is created.
Namespace create N1
Object create N1::b -set x 1
N1 evalGlobalInScope {Object create a -set y [b get x]}
puts "access the global object: [a get y]"
We can also nest invocations to evalGlobalInScope, making both the namespace
context of N1 and N2 accessible.
N1 evalGlobalInScope {
N2 evalGlobalInScope {
# some code accessing N1 and N2 objects
}
}
<namespaceID> evalInScope <code>
This methods enables you evaluate code in a namespace scope.
That is, the objects in this namespace are accessible to the evaluated code,
and newly created objects will be created in this namespace. In other words,
this methods enables you to write namespace code without using
namespace qualifiers.
In the following code, we create Namespace N1 and an object b in it.
Using evalInScope we can access b without namespace qualifier, and an object
N1::b is created.
Namespace create N1
N1 evalInScope {Object create b -set x 1}
puts "access the namespace object: [N1::b get x]"
We can also nest invocations to evalInScope, making both the namespace
scope of N1 and N2 accessible.
N1 evalInScope {
N2 evalInScope {
# some code accessing N1 and N2 objects
}
}
<namespaceID> getMembers
This methods returns a list of all objects that have been created in the scope of
a namespace. The method returns fully qualified object names.
In the following code, we create a Namespace N1 and two objects b1 and b2 in it.
We use getMembers to retrieve the namespace member list.
Namespace create N1
N1 evalInScope {
Object create b1
Object create b2
}
puts "list of namespace members: [N1 getMembers]"
<namespaceID> isMember <object name>
This methods returns true, if an object is a member of a namespace, and
false, if not.
In the following code, we create a Namespace N1 and two objects b1 and b2 in it.
Then we check various objects, if they are members of N1.
Namespace create N1
N1 evalInScope {
Object create b1
Object create b2
}
Object create b3
puts "is namespace member? [N1 isMember N1::b1] [N1 isMember N1::b2] [N1 isMember b3]"
<namespaceID> unnameMembers
This methods unnames all members of a namespace, and hence allows them to be
garbage collected.
In the following code, we create a Namespace N1 and two objects b1 and b2 in it.
After that we unname the members, so that they get garbage collected (as there are no
other references to them). Hence the namespace member list then is empty.
Namespace create N1
N1 evalInScope {
Object create b1
Object create b2
}
N1 unnameMembers
puts "list of namespace members: [N1 getMembers]"
Namespace::NamespaceClass is the class of Namespace. Its methods can
hence be directly called on Namespace.
Namespace evalGlobal <code>
This methods enables you to force code to be evaluated in the global namespace.
That is, if you are in another namespace, this methods lets you access the global
namespace.
In the following code, we create a global object a, even though we are evaluating
in the context of the namespace N1:
Namespace create N1
N1 evalInScope {
Namespace evalGlobal {Object create a}
}
a set x 1
Namespace getNamespace <object name>
Given an object name, this methods returns the namespace qualifier of the namespace,
this object is located in. It returns an empty string for objects located in the global
namespace.
In the following code, we obtain the namespace of an object:
Namespace create UML
Object create UML::Classifier
puts "Namespace of Classifier: [Namespace getNamespace UML::Classifier]"