Namespace and Uses

In Oxygene, all Types are contained in a namespace. You cna think of a namespace as a longer version of a name, that helps group related types together, and to avoid name ambiguity between types with the same name (but in different namespaces).

A type"s full name is its namespace, followed by a dot, followed by the type's short name. The namespace itself may contain additional dots, to indicateb a nested hierarchy of namespaces:

MyCompany.AHelperClass
MyCompany.MyProject.SomeClass

Here, both "MyCompany" and "MyCompany.MyProject" are (separate and distinguished) namespaces. And "AHelperClass" and "SomeClass" are the short names of two classes defined therein.

It is common to use a company or individual's name as the root portion of namespaces for custom code, to (virtually) eliminate the chance of overlap with code written by other people. For example, all RemObjects code uses namespaces startung with "RemObjects."; that is followed by the name of the prodduct, e.g. "RemObjects.Elements.", "RemObjects.DataAbstract.", and so forth.

Declaring A Namespace

In Oxygene every source file starts with the namespace keyword, followed by the name of the namespace that everything else contained in the file be put into (optionally, this name can be omitted, and type will be generated namespace-less. But thisn is very rarely done, and discouraged).

namespace MyCompany.MyProject;

...

end.

This declaration affects two things:

  1. By default, all types declared in the file will become part of this namespace.
  2. All types from this namespace — no matter where they are defined — will be "in scope" for the file.

What does this mean, exactly? Let's have a closer look.

1. By default, all types declared in the file will become part of this namespace. This means that if we define a type as follows:

namespace MyCompany.MyProject

type
  MyClass = class
    ...
  end;

then the MyClass class will automatically be considered part of the MyCompany.MyProject namespace. Its so-called *full name will this be "MyCompany.MyProject.MyClass". And this full name is how the class can be referred to everywhere.

2. All types from this namespace will be "in scope" for the file. This means that if we add a second (or more) file to our project and also begin it with namespace MyCompany.MyProject, these files will be part of the same namespace, and all types from that namespace will be in scope in all the files (no matter which file they were declared in). As such, we can refer to the above class simply as MyClass — because it is in the same namespace.

One can add as many files to a project as needed and they can all share the same namespace. In most (smallish) projects that only have a single namespace, there is no need to worry about adding namespaces to the uses clause (more on that below), just to access classes from within the project's code base. All types are automatically in scope in all source files (of the same namespace).

Of course, while it is common for small to medium projects to just use a single namespace, it is also common to declare different namespaces across a project in order to better partition parts of the project — for example one could have a MyCompany.MyProject namespace for the bulk of a project, but a MyCompany.MyProject.MySubSystem namespace for a certain sub-system of the project.

Regardless of namespace, all types declared in a project will be available all throughout the project (unless they are marked for unit level visibility only) by their full name, and all types marked as public will also be available outside of the project (i.e. when you are creating a library that will be referenced from other projects).

Code in the MyCompany.MyProject namespace could refer to a type from the syb-system simply by using it's full name:"

var x := new SomeClassFromTheMainNamespace(); // no need to specify the full name
var y := new MyCompany.MyProject.MySubSystem.SubSytemClass();

Uses Clauses

Of course, it would become cumbersome to always refer to types from other namespaces using their full name – especially if the same type, or many types from the sanem namespace(s) are used frequently through-out a source file.

By providing a uses clause with a list of namespaces at the top of the file, these additional namespaces can be brought "into scope" as well, so that anything declared in them can now also be accessed using the short name.

namespace MyCompany.MyProject;

uses
  MyCompany.MyProject.MySubSystem;

...

var y := new SubSytemClass(); // MyCompany.MyProject.MySubSystem is now in scope!

Resolving Ambiguities

If more than one namespace in scope declare a type of the same (short) name, using that name will refer the one in the namespace that is most towards the end of the uses clause. Of course you can still use the ful type name, to be sure, or to refer to one of the other types of the same name:

namespace MyCompany.MyProject;

uses
  MyCompany.MyProject.MySubSystemA,
  MyCompany.MyProject.MySubSystemB,

...

var y := new SubSytemClass(); // comes from MyCompany.MyProject.MySubSystemB
var z := new MyCompany.MyProject.MySubSystemA.SubSytemClass(); // explicitly use the type from MySubSystemB

WildCards

In addition to listing individual namespaces, the uses clause also allows the asterisk character as a wildcard, to include a namespace and all its sub-namespaces. For example, uses MyCompany.MyProject.* would add MyCompany.MyProject.SubSystemA and all the rest to the scope, including recursive sub-namespaces.

namespace MyCompany.MyProject;

uses
  MyCompany.MyProject.*;

Standard Namespaces

Certain System namespaces will be in scope by default and do not manually need to be listed in the uses clause for their types to be accessible by their short name.

  • The RemObjects.Elements.System namespace contains compiler-intrinsic types, such as Integer, System Functions and other elements, and is always first in scope.

  • On .NET, the System namespace contains many core classes, such as String and Object, and is always second in scope.

  • On Java, the java.lang namespaces contain many core classes, such as String and Object, and are always second in scope.

  • On Cocoa, the rtl.* namespace contains the C runtime library, core types and many core C-based APIs and is always second in scope.

(On Island, all standard types are in the above-mentioned RemObjects.Elements.System)

Project-Wide Default Uses Clauses

In addition, you can specify a list of namespaces be in scopr for all files via the "Default Uses Clause" Project Setting. Any namespaces in that list will be in scope before those listed in an individual source file's uses clause (in alphabetical order, with RemObjects.Elements.RTL, of present, last).

See Also