We’re here to help you

Menu

Namespaces

All component, interface, and type definitions can be defined in a namespace, which provides name scoping. The scope can be used when referring to such a definition.

Namespace Syntax

A namespace has a name, and within its scope components, interfaces, types, and sub-namespaces can be defined.

A syntax example:

namespace MyNamespace
{
  extern MyString $std::string$;

  interface MyInterface
  {
    enum MyEnumType { Val1, Val2, Val3 };
    in MyEnumType myValuedEvent(MyString s);
    out void myReply();

    behaviour
    {
      on myValuedEvent : { reply (MyEnumType.Val3); }
    }
  }
}

In this example namespace MyNamespace is introduced. In its scope data type MyString and interface MyInterface are defined.

An example with nested namespaces introduces namespace Mynamespace1, and within that (among others) namespace MyNamespace2, which itself contains interface MyInterface:

namespace MyNamespace1
{
  extern MyString $std::string$;

  namespace MyNamespace2
  {
    interface MyInterface
    {
      enum MyEnumType { Val1, Val2, Val3 };
      in MyEnumType myValuedEvent(MyString s);
      out void myReply();

      behaviour
      {
        on myValuedEvent : { reply (MyEnumType.Val3); }
      }
    }
  }
}

Namespace Re-definition

It is allowed to spread the definition of types, interfaces, components, and sub-namespaces over multiple instances of a namespace scope. This is most useful since in a 'real' project definitions are spread over multiple files.

So

namespace MyNamespace1
{
  extern MyString $std::string$;

  interface MyInterface { ... }
}

is equivalent to

namespace MyNamespace1
{
  extern MyString $std::string$;
}

namespace MyNamespace1
{
  interface MyInterface { ... }
}

Referencing

When within namespace MyNamespace MyThing is defined, then outside that namespace it is referred to by prefixing it with the name of that namespace and a dot, as in: MyNamespace.MyThing

Within its own namespace the short name MyThing is to be used.

In complex cases it may be necessary to refer to the global namespace which has an empty name; this results in name references starting with a dot, as can be seen in the following somewhat convoluted example.

namespace foo {
  interface I {
    enum Bool {F,T};
    in Bool e();
    out void a();

    behaviour {
      on e: {a; reply (Bool.T); }
    }
  }
}

namespace inner {
  namespace foo {
    interface I {
      enum Bool {f,t};
      in Bool e();
      out void a();

      behaviour { .... }
    }
  }
  component space {
    provides foo.I inner;
    provides .foo.I fooi;

    behaviour {
      foo.I.Bool inner_state = foo.I.Bool.t;
      .foo.I.Bool foo_state = .foo.I.Bool.T;
      on inner.e(): {...}
      on fooi.e(): {...}
    }
  }
}

namespace bar {
  component c {
    provides foo.I i;
    behaviour {
      foo.I.Bool state = foo.I.Bool.T;
      on i.e(): {...}
    }
  }
}

which defines:

  • interface foo.I with local enum foo.I.Bool

  • interface inner.foo.I with local enum inner.foo.I.Bool

  • component inner.space

  • component bar.c

The two variables defined in component inner.space have types foo.I.Bool and .foo.I.Bool respectively. The first type expands to inner.foo.I.Bool since it is defined in namespace inner. The starting dot in the second definition prevents this expansion.

Shorthand Namespace Syntax

In trivial cases, e.g. where only one definition is provided within a namespace, a dot notation can be used. Using this notation,

namespace MyNamespace1
{
  namespace MyNamespace2
  {
    extern MyString $std::string$;
  }
  interface MyInterface { ... }
}

can be written as:

extern MyNamespace1.MyNamespace2.MyString $std::string$;
interface MyNamespace1.MyInterface { ... }

If you have questions that weren’t answered by this Guide,
let our support team help you out.

Enjoy this article? Don't forget to share.