Create a Module from an AST

Module::eval_ast_as_new

Encapsulated environment

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

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

See also

See Export Variables, Functions and Sub-Modules from Script 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'