Neko Modules

Each compiled Neko file is considered its own separate module, with its own scope. Values within the module may be exported by adding it as a field to the global $exports object. $exports will then be available to outside modules.

When importing a module, the local path is searched along with any paths listed in the NEKOPATH environment variable. The paths in NEKOPATH should be separated by colons (:).

Exporting Values

Exporting is quite simple, just add any value that should be made accessible into the $exports object, using any name:

var s = "hello!";

var f = function(x) { x };

i = 100101;

$exports.hello = s;
$exports.identity = f;
$exports.number = i;

Importing Values

Values are “imported” by loading in the $exports object from another file and assigning it to a variable. Note that the module which is being loaded will actually be executed as it is loaded. This means the $exports object may be generated dynamically.

To load in a module, there is a global object called $loader with a loadmodule method for loading modules. Keep in mind, however, that modules written in Neko are handled differently than those written in C. For loading C modules, see here.

loadmodule takes two arguments: the name of the module minus the “.n” extension and a loader object. In most cases, the $loader object itself would be used for the second argument.

If the code above were compiled into a file named “test.n”, the following code could be used to load it:

var test = $loader.loadmodule("test", $loader);

$print(test.hello); //prints "hello!"

$print(test.number); //prints "100101"

$print(test.identity("test!")); //prints "test!"

The imported object essentially becomes a shared object between modules, so it is possible to modify an $exports object at runtime and have the changes reflected in another module. The first block of code below is saved in a module named “test” and loaded by the second block of code. The second block of code calls a function in the first, which adds a new exported value. This exported value is then available in the second block of code.

//test.neko

var add_export = function(x) { $exports.more = x };

$exports.add_export = add_export;
var test = $loader.loadmodule("test", $loader);

test.add_export("hello!");

$print(test.more); //prints "hello!"

The object returned from loadmodule also includes the field __module which is an abstract value containing information regarding the loaded module. This field can be used in conjunction with the module standard library, documented here.

var test = $loader.loadmodule("test", load);

var f = $loader.loadprim("std@module_name", 1);
$print(f(test.__module));  //prints "test"