|
3.2 Namespaces[This section (and the implementation of namespaces in GNU Smalltalk) is based on the paper Structured Symbolic Name Spaces in Smalltalk, by Augustin Mrazik.]
3.2.1 Introduction
The standard Smalltalk-80 programming environment supports symbolic
identification of objects in one global namespace--in the In a development dealing with modelling of real systems, polymorphic symbolic identification is often needed. This means that it should be possible to use the same name for different classes or other global variables. Let us mention class Module as an example which would mean totaly different things for a programmer, for a computer technician and for a civil engineer or an architect. This issue becomes inevitable if we start to work in a Smalltalk environment supporting persistence. Polymorphism of classes becomes necessary in the moment we start to think about storing classes in the database since after restoring them into the running Smalltalk image a mismatch with the current symbolic identification of the present classes could occur. For example you might have the class Module already in your image with the meaning of a program module (e.g. in a CASE system) and you might attempt to load the class Module representing a part of the computer hardware from the database for hardware configuration system. The last class could get bound to the #Module symbol in the Smalltalk system dictionary and the other class could remain in the system as unbound class with full functionality, however, it could not be accessed anymore at the symbolical level in the source code. Objects which have to be identified in the source code of methods or message sends by their names are included in Smalltalk which is a sole instance of SystemDictionary. Such objects may be identified simply by stating their name as primary in a Smalltalk statement. The code is compiled in the Smalitalk environment and if such a primary is found it is bound to the corresponding object as receiver of the rest of the message send. In this way Smalltalk as instance of SystemDictionary represents the sole symbolic name space in the Smalltalk system. In the following text the symbolic name space will be called simply environment to make the text more clear.
3.2.2 ConceptsTo support polymorphic symbolical identification several environments will be needed. The same name may be located concurrently in several environments and point to diverse objects. However, symbolic navigation between these environments is needed. Before approaching the problem of the syntax to be implemented and of its very implementation, we have to point out which structural relations are going to be established between environments.
Since the environment has first to be symbolically identified to gain
access to its global variables, it has to be a global variable in
another environment. Obviously, However, the symbolic identification should be unambiguous although it will be polymorphic. This is why we should avoid cycles in the environment graph. Cycles in the graph could cause also other problems in the implementation, e.g. unability to use recursive algorithms. This is why in general the environments build a directed acyclic graph(3). Let us call the partial ordering relation which occurs between the two environments to be inheritance. Sub-environments inherits from their super-environments. Not only that "inheritance" is the standard term for the partial ordering relation in the lattice theory but the feature of inheritance in the meaning of object-orientation is associated with this relation. This means that all associations of the super-environment are valid also in its sub-environments unless they are locally redefined in the sub-environment.
A super-environment includes all its sub-enviroments as associations under
their names. The sub-environment includes its super-environment under the
symbol
The inheritance links to the super-environments are used in the lookup for a
potentially inherited global variable. This includes lookups by a compiler
searching for a variable and lookups via methods such as
3.2.3 SyntaxGlobal objects of an environment (local or inherited) may be referenced by their symbol used in the source code, e.g.
if the If an object has to be referenced from another environment (i.e. which is not on the inheritance link) it has to be referenced either relatively to the position of the current environment (using the Super symbol), or absolutely (using the "full pathname" of the object, navigating from Smalltalk through the tree of sub-environments). For the identification of global objects in another environment a "pathname" of symbols is used. The symbols are separated by blanks, i.e. the "look" to be implemented is that of
and of
Its similarity to a sequence of message sends is not casual, and suggests the following syntax for write access:(4)
This resembles the way accessors are used for other objects. As it is custom in Smalltalk, however, we are reminded by uppercase letters that we are accessing global objects. In addition, a special syntax has been implemented that returns the Association object for a particular global: so the last example above can be written also like
This special kind of literal (called a variable binding) is also valid inside literal arrays.
3.2.4 Implementation
A superclass of To handle inheritance, the following methods have to be defined or redefined in Namespace (not in RootNamespace):
For programs to be able to process correctly the "pathnames" and the
accessors, this feature must be implemented directly in RootNamespace;
it is easily handled through the standard The most important task of the Namespace class is to provide organization for the most important global objects in the Smalltalk system--for the classes. This importance becomes even more crucial in the structured environments which is first of all a framework for class polymorphism.
In Smalltalk the classes have the instance variable Of course, any class (just like any other object) may be included concurrently in several environments, even under different symbols in the same or in diverse environments. We can consider this 'alias names' of the particular class or global variable. However, classes may be referenced under the other names or in other environments as their mother environment e.g. for the purpose of intance creation or messages to he class (class methods), but they cannot be compiled in other environment. If a class compiles its methods it always compiles them in its mother environment even if this compilation is requested from another environment. If the syntax is not correct in the mother environment, a compilation error simply occurs. An important issue is also the name of the class answered by the class for the purpose of its identification in diverse tools (e.g. in a browser). This has to be change to reflect the environment in which it is shown, i.e. the method `nameIn: environment' has to be implemented and used on proper places. These methods are not all which have to redefined in the Smalltalk system to achieve full functionality of structured environments. In particular, changes have to be made to the behavior classes, to the user interface, to the compiler, to a few classes supporting persistance. An interesting point that could not be noticed is that the environment is easier to use if evaluations (doits) are parsed as if UndefinedObject's mother environment was the current namespace.
3.2.5 Using namespacesUsing namespaces if often merely a matter of rewriting the loading script this way:
Also remember that pool dictionaries are actually "pool namespaces", in the
sense that including a namespace in the pool dictionaries list will
automatically include its superspaces too. Declaring a namespace as a
pool dictionaries is similar in this way to C++'s Finally, be careful when working with fundamental system classes. Although you can use code like
or the equivalent syntax
Unfortunately this problem is not easy to solve since Smalltalk has to cache
the OOPs of determinate class objects for speed--it would not be feasible
to lookup the environment to which sender of a message belongs every time
the So, GNU Smalltalk namespaces cannot yet solve 100% of the problem of clashes between extensions to a class--for that you'll still have to rely on prefixes to method names. But they do solve the problem of clashes between class names and pool dictionary names, so you might want to give them a try. An example of using namespaces is given by the `examples/Publish.st' file in the GNU Smalltalk source code directory. |