This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/rhai_engine/rhaibook/engine/def-var.md
2025-04-19 08:10:30 +02:00

4.0 KiB

Variable Definition Filter

{{#include ../links.md}}

Although it is easy to disable variable [shadowing] via [Engine::set_allow_shadowing][options], sometimes more fine-grained control is needed.

For example, it may be the case that not all variables [shadowing] must be disallowed, but that only a particular variable name needs to be protected and not others. Or only under very special circumstances.

Under this scenario, it is possible to provide a filter closure to the [Engine] via Engine::on_def_var that traps variable definitions (i.e. [let][variable] or [const][constant] statements) in a Rhai script.

The filter is called when a [variable] or [constant] is defined both during runtime and compilation.

let mut engine = Engine::new();

// Register a variable definition filter.
engine.on_def_var(|is_runtime, info, context| {
    match (info.name, info.is_const) {
        // Disallow defining 'MYSTIC_NUMBER' as a constant!
        ("MYSTIC_NUMBER", true) => Ok(false),
        // Disallow defining constants not at global level!
        (_, true) if info.nesting_level > 0 => Ok(false),
        // Throw any exception you like...
        ("hello", _) => Err(EvalAltResult::ErrorVariableNotFound(info.name.to_string(), Position::NONE).into()),
        // Return Ok(true) to continue with normal variable definition.
        _ => Ok(true)
    }
});

Function Signature

The function signature passed to Engine::on_def_var takes the following form.

Fn(is_runtime: bool, info: VarDefInfo, context: EvalContext) -> Result<bool, Box<EvalAltResult>>

where:

Parameter Type Description
is_runtime bool true if the [variable] definition event happens during runtime, false if during compilation
info VarDefInfo information on the [variable] being defined
context [EvalContext] the current evaluation context

and VarDefInfo is a simple struct that contains the following fields:

Field Type Description
name &str [variable] name
is_const bool true if the definition is a [const][constant]; false if it is a [let][variable]
nesting_level usize the current nesting level; the global level is zero
will_shadow bool will this [variable] [shadow] an existing [variable] of the same name?

and [EvalContext] is a type that encapsulates the current evaluation context.

Return value

The return value is Result<bool, Box<EvalAltResult>> where:

Value Description
Ok(true) normal [variable] definition should continue
Ok(false) [throws][exception] a runtime or compilation error
Err(Box<EvalAltResult>) error that is reflected back to the [Engine]

During compilation (i.e. when `is_runtime` is `false`), `EvalAltResult::ErrorParsing` is passed
through as the compilation error.

All other errors map to `ParseErrorType::ForbiddenVariable`.