Modules
module
declares the name of a module. While optional, it is recommended to use it, at least for documentation purposes. The basename of the source file must match the name declared with module
. The extension of the source file must be nit
.
A module is made of, in order:
- the module declaration;
- module importations;
- class definitions (and refinements) ;
- top-level function definitions (and redefinitions) ;
- main instructions .
Module Importation
import
declares dependencies between modules. By default (that is without any import
declaration), a module publicly imports the module standard
. Dependencies must not produce cycles. By importing a module, the importer module can see and use classes and properties defined in the imported module.
import
indicates a public importation. Importers of a given module will also import its publicly imported modules. An analogy is using#include
in a header file (.h
) in C/C++.private import
indicates a private importation. Importers of a given module will not automatically import its privately imported modules. An analogy is using#include
in a body file (.c
) in C/C++.intrude import
indicates an intrusive importation.intrude
import
bypasses theprivate
visibility and gives to the importer module full access on the imported module. Such an import may only be considered when modules are strongly bounded and developed together. The closest, but insufficient, analogy is something like including a body file in a body file in C/C++.
Visibility
By default, all classes, methods, constructors and virtual types are public which means freely usable by any importer module. Once something is public it belongs to the API of the module and should not be changed.
private
indicates classes and methods that do not belong to the API. They are still freely usable inside the module but are invisible in other modules (except those that use intrude import
).
protected
indicates restricted methods and constructors. Such methods belong to the API of the module but they can only be used with the self
receiver. Basically, protected
methods are limited to the current class and its subclasses. Note that inside the module (and in
intrude importers), there is still no restriction.
Visibility of attributes is more specific and is detailed in its own section.
module m1 class Foo fun pub do ... protected fun pro do ... private fun pri do ... end private class Bar fun pri2 do ... end var x: Foo = ... var y: Bar = ... # All OK, it is # inside the module x.foo x.pro x.pro y.pri2
module m2 import m1 class Baz super Foo fun derp do self.pro # OK end end var x: Foo = ... x.pub # OK x.pro # Compile error: # pro is protected x.pri # Compile error: # unknown method pri var y: Bar # Compile error: # unknown class Bar
Visibility Coherence
In order to guarantee the coherence in the visibility, the following rules apply:
Classes and properties privately imported are considered private: they are not exported and do not belong to the API of the importer.
Properties defined in a private class are private.
A static type is private if it contains a private class or a private virtual type.
Signatures of public and protected properties cannot contain a private static type.
Bounds of public generic class and public virtual types cannot contain a private static type.