1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
= Nickle Namespaces
Namespaces collect related variable and function names and allow control over visibility.
A number of Nickle builtins are gathered into builtin namespaces that may be used.
The following builtin namespaces have sections in this tutorial:
`Math`::
Useful mathematical functions.
`File`::
File input/output with the 'file' type.
`Thread`::
Concurrent processing.
`Semaphore and Mutex`::
Synchronization of threads.
`String`::
Useful functions for strings.
An example namespace might be declared like this:
----
namespace Example {
int blah = 1;
public int a = 0;
int function bar(int a) {
...
}
protected int function foo(int a) {
...
}
}
----
The keyword `namespace` is followed by the name of the namespace and a
list of statements that declare names in the namespace. The
publication of those declarations, e.g. `public` or `protected`
defines how visible they will be outside the namespace. The namespace
itself may be preceeded by publication information, _but this has no
bearing on the names within the namespace_; it defines the visibility
of the name of the namespace. If the example above had been declared
----
protected namespace Example {
...
}
----
Then the names within `Example` would have the same visibility as
always, but `Example` itself would be protected in whatever namespace
it belongs to. In this case, it belongs to the top-level namespace,
but namespaces can be nested within each other, which makes the
visibility of their own names important.
== Extend
`extend namespace` _name_ `{` _statement-list_ `}`
Names may be added to a namespace after it is initially defined with the `extend` command.
The namespace `name` is reopened and the new `statement-list` is added to the previous ones.
For example,
----
extend namespace Example {
string[*] greeting = [2]{ "hello", "world" };
}
----
Adds `greeting` to the names already defined in ``Example``.
== Peering inside
_namespace_ `::` _name_ +
`import` _namespace_
The `::` operator refers to a `name`, which is in `namespace`,
analogously to a structure dereference. If `name` also refers to a
namespace, its names too are visible this way. Either `protected` or
`public` names are visible in this way.
An `import` statement brings all the public names in `namespace` into
scope, overshadowing conflicting names. Thereafter, those names may
be used normally.
A variable is declared with one of three visibilities that defines how
it is visible outside its namespace:
* `public` may be seen outside with `::` or imported
* `protected` may be seen outside with `::` but not imported
* if neither is specified, it may not be seen outside at all
Thus, in our example namespace `Example`:
* `blah`, `bar`, and `greeting` have no visibility specified and may
only be used inside `Example`.
* both `a` (which is public) and `foo` (which is protected) may be
seen with `::`.
* an `import` will only bring `a` into scope, as it is the only name
that is public.
|