Create a Module from an AST

Module::eval_ast_as_new


`Module::eval_ast_as_new` encapsulates the entire [`AST`] into each function call, merging the
[module namespace][function namespace] with the [global namespace][function namespace].

Therefore, [functions] defined within the same [module] script can cross-call each other.

See [_Export Variables, Functions and Sub-Modules from Script_][`export`] for details on how to prepare
a Rhai script for this purpose as well as to control which [functions]/[variables] to export.

A module can be created from a single script (or pre-compiled AST) containing global variables, functions and sub-modules via Module::eval_ast_as_new.

When given an AST, it is first evaluated (usually to import modules and set up global constants used by functions), then the following items are exposed as members of the new module:

Examples

Don’t forget the export statement, otherwise there will be no variables exposed by the module other than non-private functions (unless that’s intentional).

use rhai::{Engine, Module};

let engine = Engine::new();

// Compile a script into an 'AST'
let ast = engine.compile(
r#"
    // Functions become module functions
    fn calc(x) {
        x + add_len(x, 1)       // functions within the same module
                                // can always cross-call each other!
    }
    fn add_len(x, y) {
        x + y.len
    }

    // Imported modules become sub-modules
    import "another module" as extra;

    // Variables defined at global level can become module variables
    const x = 123;
    let foo = 41;
    let hello;

    // Variable values become constant module variable values
    foo = calc(foo);
    hello = `hello, ${foo} worlds!`;

    // Finally, export the variables and modules
    export x as abc;            // aliased variable name
    export foo;
    export hello;
"#)?;

// Convert the 'AST' into a module, using the 'Engine' to evaluate it first
// A copy of the entire 'AST' is encapsulated into each function,
// allowing functions in the module script to cross-call each other.
let module = Module::eval_ast_as_new(Scope::new(), &ast, &engine)?;

// 'module' now contains:
//   - sub-module: 'extra'
//   - functions: 'calc', 'add_len'
//   - constants: 'abc' (renamed from 'x'), 'foo', 'hello'