Update docs regarding modules.
This commit is contained in:
@@ -19,14 +19,14 @@ script += "x + y";
|
||||
|
||||
let result = eval(script); // <- look, JavaScript, we can also do this!
|
||||
|
||||
print("Answer: " + result); // prints 42
|
||||
result == 42;
|
||||
|
||||
print("x = " + x); // prints 10: functions call arguments are passed by value
|
||||
print("y = " + y); // prints 32: variables defined in 'eval' persist!
|
||||
x == 10; // prints 10: functions call arguments are passed by value
|
||||
y == 32; // prints 32: variables defined in 'eval' persist!
|
||||
|
||||
eval("{ let z = y }"); // to keep a variable local, use a statement block
|
||||
|
||||
print("z = " + z); // <- error: variable 'z' not found
|
||||
print(z); // <- error: variable 'z' not found
|
||||
|
||||
"print(42)".eval(); // <- nope... method-call style doesn't work with 'eval'
|
||||
```
|
||||
|
@@ -14,8 +14,9 @@ fn sub(x, y,) { // trailing comma in parameters list is OK
|
||||
return x - y;
|
||||
}
|
||||
|
||||
print(add(2, 3)); // prints 5
|
||||
print(sub(2, 3,)); // prints -1 - trailing comma in arguments list is OK
|
||||
add(2, 3) == 5;
|
||||
|
||||
sub(2, 3,) == -1; // trailing comma in arguments list is OK
|
||||
```
|
||||
|
||||
|
||||
@@ -35,8 +36,9 @@ fn add2(x) {
|
||||
return x + 2; // explicit return
|
||||
}
|
||||
|
||||
print(add(2, 3)); // prints 5
|
||||
print(add2(42)); // prints 44
|
||||
add(2, 3) == 5;
|
||||
|
||||
add2(42) == 44;
|
||||
```
|
||||
|
||||
|
||||
|
@@ -22,6 +22,8 @@ The `export` statement, which can only be at global level, exposes selected vari
|
||||
|
||||
Variables not exported are _private_ and hidden to the outside.
|
||||
|
||||
Everything exported from a module is **constant** (**read-only**).
|
||||
|
||||
```rust
|
||||
// This is a module script.
|
||||
|
||||
@@ -49,8 +51,6 @@ All functions are automatically exported, _unless_ it is explicitly opt-out with
|
||||
|
||||
Functions declared [`private`] are hidden to the outside.
|
||||
|
||||
Everything exported from a module is **constant** (**read-only**).
|
||||
|
||||
```rust
|
||||
// This is a module script.
|
||||
|
||||
|
@@ -1,56 +0,0 @@
|
||||
Implement a Custom Module Resolver
|
||||
=================================
|
||||
|
||||
{{#include ../../links.md}}
|
||||
|
||||
For many applications in which Rhai is embedded, it is necessary to customize the way that modules
|
||||
are resolved. For instance, modules may need to be loaded from script texts stored in a database,
|
||||
not in the file system.
|
||||
|
||||
A module resolver must implement the trait [`rhai::ModuleResolver`][traits],
|
||||
which contains only one function: `resolve`.
|
||||
|
||||
When Rhai prepares to load a module, `ModuleResolver::resolve` is called with the name
|
||||
of the _module path_ (i.e. the path specified in the [`import`] statement). Upon success, it should
|
||||
return a [`Module`]; if the module cannot be load, return `EvalAltResult::ErrorModuleNotFound`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```rust
|
||||
use rhai::{ModuleResolver, Module, Engine, EvalAltResult};
|
||||
|
||||
// Define a custom module resolver.
|
||||
struct MyModuleResolver {}
|
||||
|
||||
// Implement the 'ModuleResolver' trait.
|
||||
impl ModuleResolver for MyModuleResolver {
|
||||
// Only required function.
|
||||
fn resolve(
|
||||
&self,
|
||||
engine: &Engine, // reference to the current 'Engine'
|
||||
path: &str, // the module path
|
||||
pos: Position, // location of the 'import' statement
|
||||
) -> Result<Module, Box<EvalAltResult>> {
|
||||
// Check module path.
|
||||
if is_valid_module_path(path) {
|
||||
// Load the custom module.
|
||||
let module: Module = load_secret_module(path);
|
||||
Ok(module)
|
||||
} else {
|
||||
Err(Box::new(EvalAltResult::ErrorModuleNotFound(path.into(), pos)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut engine = Engine::new();
|
||||
|
||||
// Set the custom module resolver into the 'Engine'.
|
||||
engine.set_module_resolver(Some(MyModuleResolver {}));
|
||||
|
||||
engine.consume(r#"
|
||||
import "hello" as foo; // this 'import' statement will call
|
||||
// 'MyModuleResolver::resolve' with "hello" as path
|
||||
foo:bar();
|
||||
"#)?;
|
||||
```
|
@@ -3,6 +3,7 @@ Import a Module
|
||||
|
||||
{{#include ../../links.md}}
|
||||
|
||||
|
||||
`import` Statement
|
||||
-----------------
|
||||
|
||||
|
@@ -1,29 +0,0 @@
|
||||
Module Resolvers
|
||||
================
|
||||
|
||||
{{#include ../../links.md}}
|
||||
|
||||
When encountering an [`import`] statement, Rhai attempts to _resolve_ the module based on the path string.
|
||||
|
||||
_Module Resolvers_ are service types that implement the [`ModuleResolver`][traits] trait.
|
||||
|
||||
There are a number of standard resolvers built into Rhai, the default being the `FileModuleResolver`
|
||||
which simply loads a script file based on the path (with `.rhai` extension attached) and execute it to form a module.
|
||||
|
||||
Built-in module resolvers are grouped under the `rhai::module_resolvers` module namespace.
|
||||
|
||||
| Module Resolver | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `FileModuleResolver` | The default module resolution service, not available under [`no_std`] or [WASM] builds. Loads a script file (based off the current directory) with `.rhai` extension.<br/>The base directory can be changed via the `FileModuleResolver::new_with_path()` constructor function.<br/>`FileModuleResolver::create_module()` loads a script file and returns a module. |
|
||||
| `StaticModuleResolver` | Loads modules that are statically added. This can be used under [`no_std`]. |
|
||||
|
||||
An [`Engine`]'s module resolver is set via a call to `Engine::set_module_resolver`:
|
||||
|
||||
```rust
|
||||
// Use the 'StaticModuleResolver'
|
||||
let resolver = rhai::module_resolvers::StaticModuleResolver::new();
|
||||
engine.set_module_resolver(Some(resolver));
|
||||
|
||||
// Effectively disable 'import' statements by setting module resolver to 'None'
|
||||
engine.set_module_resolver(None);
|
||||
```
|
@@ -1,30 +0,0 @@
|
||||
Create a Module from Rust
|
||||
========================
|
||||
|
||||
{{#include ../../links.md}}
|
||||
|
||||
To load a custom module (written in Rust) into an [`Engine`], first create a [`Module`] type,
|
||||
add variables/functions into it, then finally push it into a custom [`Scope`].
|
||||
|
||||
This has the equivalent effect of putting an [`import`] statement at the beginning of any script run.
|
||||
|
||||
```rust
|
||||
use rhai::{Engine, Scope, Module, i64};
|
||||
|
||||
let mut engine = Engine::new();
|
||||
let mut scope = Scope::new();
|
||||
|
||||
let mut module = Module::new(); // new module
|
||||
module.set_var("answer", 41_i64); // variable 'answer' under module
|
||||
module.set_fn_1("inc", |x: i64| Ok(x+1)); // use the 'set_fn_XXX' API to add functions
|
||||
|
||||
// Push the module into the custom scope under the name 'question'
|
||||
// This is equivalent to 'import "..." as question;'
|
||||
scope.push_module("question", module);
|
||||
|
||||
// Use module-qualified variables
|
||||
engine.eval_expression_with_scope::<i64>(&scope, "question::answer + 1")? == 42;
|
||||
|
||||
// Call module-qualified functions
|
||||
engine.eval_expression_with_scope::<i64>(&scope, "question::inc(question::answer)")? == 42;
|
||||
```
|
@@ -15,7 +15,7 @@ The following primitive types are supported natively:
|
||||
| **[`Array`]** (disabled with [`no_index`]) | `rhai::Array` | `"array"` | `"[ ?, ?, ? ]"` |
|
||||
| **[Object map]** (disabled with [`no_object`]) | `rhai::Map` | `"map"` | `"#{ "a": 1, "b": 2 }"` |
|
||||
| **[Timestamp]** (implemented in the [`BasicTimePackage`][packages], disabled with [`no_std`]) | `std::time::Instant` ([`instant::Instant`] if not [WASM] build) | `"timestamp"` | _not supported_ |
|
||||
| **[Function pointer]** | _None_ | `Fn` | `"Fn(foo)"` |
|
||||
| **[Function pointer]** | `rhai::FnPtr` | `Fn` | `"Fn(foo)"` |
|
||||
| **[`Dynamic`] value** (i.e. can be anything) | `rhai::Dynamic` | _the actual type_ | _actual value_ |
|
||||
| **System integer** (current configuration) | `rhai::INT` (`i32` or `i64`) | `"i32"` or `"i64"` | `"42"`, `"123"` etc. |
|
||||
| **System floating-point** (current configuration, disabled with [`no_float`]) | `rhai::FLOAT` (`f32` or `f64`) | `"f32"` or `"f64"` | `"123.456"` etc. |
|
||||
|
Reference in New Issue
Block a user