Revise docs.

This commit is contained in:
Stephen Chung 2020-07-28 10:25:57 +08:00
parent f05cd1fdf3
commit b70fd35f4a
9 changed files with 91 additions and 51 deletions

View File

@ -27,12 +27,11 @@ Standard features
* Easily [call a script-defined function](https://schungx.github.io/rhai/engine/call-fn.html) from Rust. * Easily [call a script-defined function](https://schungx.github.io/rhai/engine/call-fn.html) from Rust.
* Fairly low compile-time overhead. * Fairly low compile-time overhead.
* Fairly efficient evaluation (1 million iterations in 0.3 sec on a single core, 2.3 GHz Linux VM). * Fairly efficient evaluation (1 million iterations in 0.3 sec on a single core, 2.3 GHz Linux VM).
* Relatively little `unsafe` code (yes there are some for performance reasons, and most `unsafe` code is limited to * Relatively little `unsafe` code (yes there are some for performance reasons).
one single source file, all with names starting with `"unsafe_"`).
* Re-entrant scripting engine can be made `Send + Sync` (via the `sync` feature). * Re-entrant scripting engine can be made `Send + Sync` (via the `sync` feature).
* [Function overloading](https://schungx.github.io/rhai/language/overload.html). * [Function overloading](https://schungx.github.io/rhai/language/overload.html).
* [Operator overloading](https://schungx.github.io/rhai/rust/operators.html). * [Operator overloading](https://schungx.github.io/rhai/rust/operators.html).
* Dynamic dispatch via [function pointers](https://schungx.github.io/rhai/language/fn-ptr.html). * Dynamic dispatch via [function pointers](https://schungx.github.io/rhai/language/fn-ptr.html) with additional support for [currying](https://schungx.github.io/rhai/language/fn-curry.html).
* Some support for [object-oriented programming (OOP)](https://schungx.github.io/rhai/language/oop.html). * Some support for [object-oriented programming (OOP)](https://schungx.github.io/rhai/language/oop.html).
* Organize code base with dynamically-loadable [modules](https://schungx.github.io/rhai/language/modules.html). * Organize code base with dynamically-loadable [modules](https://schungx.github.io/rhai/language/modules.html).
* Serialization/deserialization support via [serde](https://crates.io/crates/serde) (requires the `serde` feature). * Serialization/deserialization support via [serde](https://crates.io/crates/serde) (requires the `serde` feature).

View File

@ -35,23 +35,20 @@ Dynamic
* Organize code base with dynamically-loadable [modules]. * Organize code base with dynamically-loadable [modules].
* Dynamic dispatch via [function pointers]. * Dynamic dispatch via [function pointers] with additional support for [currying].
* Some support for [object-oriented programming (OOP)][OOP]. * Some support for [object-oriented programming (OOP)][OOP].
* Serialization/deserialization support via [`serde`].
Safe Safe
---- ----
* Relatively little `unsafe` code (yes there are some for performance reasons, and most `unsafe` code is limited to * Relatively little `unsafe` code (yes there are some for performance reasons).
one single source file, all with names starting with `"unsafe_"`).
* Sand-boxed - the scripting [`Engine`], if declared immutable, cannot mutate the containing environment unless explicitly permitted (e.g. via a `RefCell`).
Rugged Rugged
------ ------
* Sand-boxed - the scripting [`Engine`], if declared immutable, cannot mutate the containing environment unless explicitly permitted (e.g. via a `RefCell`).
* Protected against malicious attacks (such as [stack-overflow][maximum call stack depth], [over-sized data][maximum length of strings], and [runaway scripts][maximum number of operations] etc.) that may come from untrusted third-party user-land scripts. * Protected against malicious attacks (such as [stack-overflow][maximum call stack depth], [over-sized data][maximum length of strings], and [runaway scripts][maximum number of operations] etc.) that may come from untrusted third-party user-land scripts.
* Track script evaluation [progress] and manually terminate a script run. * Track script evaluation [progress] and manually terminate a script run.
@ -61,6 +58,8 @@ Flexible
* Re-entrant scripting [`Engine`] can be made `Send + Sync` (via the [`sync`] feature). * Re-entrant scripting [`Engine`] can be made `Send + Sync` (via the [`sync`] feature).
* Serialization/deserialization support via [`serde`](https://crates.io/crates/serde).
* Support for [minimal builds] by excluding unneeded language [features]. * Support for [minimal builds] by excluding unneeded language [features].
* Supports [most build targets](targets.md) including `no-std` and [WASM]. * Supports [most build targets](targets.md) including `no-std` and [WASM].

View File

@ -69,17 +69,22 @@ The only practical way to ensure that a function is a correct one is to use [mod
i.e. define the function in a separate module and then [`import`] it: i.e. define the function in a separate module and then [`import`] it:
```rust ```rust
message.rhai: ----------------
| message.rhai |
----------------
fn message() { "Hello!" } fn message() { "Hello!" }
script.rhai:
fn say_hello() { ---------------
import "message" as msg; | script.rhai |
print(msg::message()); ---------------
}
say_hello(); fn say_hello() {
import "message" as msg;
print(msg::message());
}
say_hello();
``` ```
@ -94,18 +99,23 @@ defined _within the script_. When called later, those functions will be searche
current global namespace and may not be found. current global namespace and may not be found.
```rust ```rust
greeting.rhai: -----------------
| greeting.rhai |
-----------------
fn message() { "Hello!" }; fn message() { "Hello!" };
fn say_hello() { print(message()); } fn say_hello() { print(message()); }
say_hello(); // 'message' is looked up in the global namespace say_hello(); // 'message' is looked up in the global namespace
script.rhai:
import "greeting" as g; ---------------
g::say_hello(); // <- error: function not found - 'message' | script.rhai |
---------------
import "greeting" as g;
g::say_hello(); // <- error: function not found - 'message'
``` ```
In the example above, although the module `greeting.rhai` loads fine (`"Hello!"` is printed), In the example above, although the module `greeting.rhai` loads fine (`"Hello!"` is printed),
@ -118,24 +128,29 @@ as possible and avoid cross-calling them from each other. A [function pointer]
to call another function within a module-defined function: to call another function within a module-defined function:
```rust ```rust
greeting.rhai: -----------------
| greeting.rhai |
-----------------
fn message() { "Hello!" }; fn message() { "Hello!" };
fn say_hello(msg_func) { // 'msg_func' is a function pointer fn say_hello(msg_func) { // 'msg_func' is a function pointer
print(msg_func.call()); // call via the function pointer print(msg_func.call()); // call via the function pointer
} }
say_hello(); // 'message' is looked up in the global namespace say_hello(); // 'message' is looked up in the global namespace
script.rhai:
import "greeting" as g; ---------------
| script.rhai |
---------------
fn my_msg() { import "greeting" as g;
import "greeting" as g; // <- must import again here...
g::message() // <- ... otherwise will not find module 'g'
}
g::say_hello(Fn("my_msg")); // prints 'Hello!' fn my_msg() {
import "greeting" as g; // <- must import again here...
g::message() // <- ... otherwise will not find module 'g'
}
g::say_hello(Fn("my_msg")); // prints 'Hello!'
``` ```

View File

@ -16,7 +16,7 @@ fn sub(x, y,) { // trailing comma in parameters list is OK
add(2, 3) == 5; add(2, 3) == 5;
sub(2, 3,) == -1; // trailing comma in arguments list is OK sub(2, 3,) == -1; // trailing comma in arguments list is OK
``` ```

View File

@ -37,12 +37,30 @@ array[0].update(); // <- call in method-call style will update 'a'
``` ```
`&mut` is Efficient Number of Parameters
------------------ --------------------
Native Rust methods registered with an [`Engine`] take _one additional parameter_ more than
an equivalent method coded in script, where the object is accessed via the `this` pointer instead.
The following table illustrates the differences:
| Function type | Parameters | Object reference | Function signature |
| :-----------: | :--------: | :--------------------: | :-----------------------------------------------------: |
| Native Rust | _n_ + 1 | First `&mut` parameter | `fn method<T, U, V>`<br/>`(obj: &mut T, x: U, y: V) {}` |
| Rhai script | _n_ | `this` | `fn method(x, y) {}` |
`&mut` is Efficient (Except for `ImmutableString`)
------------------------------------------------
Using a `&mut` first parameter is highly encouraged when using types that are expensive to clone, Using a `&mut` first parameter is highly encouraged when using types that are expensive to clone,
even when the intention is not to mutate that argument, because it avoids cloning that argument value. even when the intention is not to mutate that argument, because it avoids cloning that argument value.
For example, the `len` method of an [array] has the signature: `Fn(&mut Array) -> INT`.
The array itself is not modified in any way, but using a `&mut` parameter avoids a cloning that would
otherwise have happened if the signature were `Fn(Array) -> INT`.
For primary types that are cheap to clone (e.g. those that implement `Copy`), For primary types that are cheap to clone (e.g. those that implement `Copy`),
including `ImmutableString`, this is not necessary. including `ImmutableString`, this is not necessary.

View File

@ -63,7 +63,9 @@ cause a stack overflow in the [`Engine`], unless stopped by setting a limit for
For instance, importing itself always causes an infinite recursion: For instance, importing itself always causes an infinite recursion:
```rust ```rust
// This file is 'hello.rhai' --------------
| hello.rhai |
--------------
import "hello" as foo; // import itself - infinite recursion! import "hello" as foo; // import itself - infinite recursion!
@ -73,11 +75,18 @@ foo::do_something();
Modules cross-referencing also cause infinite recursion: Modules cross-referencing also cause infinite recursion:
```rust ```rust
// This file is 'hello.rhai' - references 'world.rhai' --------------
| hello.rhai |
--------------
import "world" as foo; import "world" as foo;
foo::do_something(); foo::do_something();
// This file is 'world.rhai' - references 'hello.rhai'
--------------
| world.rhai |
--------------
import "hello" as bar; import "hello" as bar;
bar::do_something_else(); bar::do_something_else();
``` ```

View File

@ -9,15 +9,15 @@ and _number_ of parameters, but not parameter _types_ since all parameters are t
New definitions _overwrite_ previous definitions of the same name and number of parameters. New definitions _overwrite_ previous definitions of the same name and number of parameters.
```rust ```rust
fn foo(x,y,z) { print("Three!!! " + x + "," + y + "," + z) } fn foo(x,y,z) { print("Three!!! " + x + "," + y + "," + z); }
fn foo(x) { print("One! " + x) } fn foo(x) { print("One! " + x); }
fn foo(x,y) { print("Two! " + x + "," + y) } fn foo(x,y) { print("Two! " + x + "," + y); }
fn foo() { print("None.") } fn foo() { print("None."); }
fn foo(x) { print("HA! NEW ONE! " + x) } // overwrites previous definition fn foo(x) { print("HA! NEW ONE! " + x); } // overwrites previous definition
foo(1,2,3); // prints "Three!!! 1,2,3" foo(1,2,3); // prints "Three!!! 1,2,3"

View File

@ -24,7 +24,7 @@ more control over what a script can (or cannot) do.
| `no_function` | Disable script-defined [functions]. | | `no_function` | Disable script-defined [functions]. |
| `no_module` | Disable loading external [modules]. | | `no_module` | Disable loading external [modules]. |
| `no_std` | Build for `no-std`. Notice that additional dependencies will be pulled in to replace `std` features. | | `no_std` | Build for `no-std`. Notice that additional dependencies will be pulled in to replace `std` features. |
| `serde` | Enable serialization/deserialization via [`serde`]. Notice that the [`serde`](https://crates.io/crates/serde) crate will be pulled in together with its dependencies. | | `serde` | Enable serialization/deserialization via `serde`. Notice that the [`serde`](https://crates.io/crates/serde) crate will be pulled in together with its dependencies. |
| `internals` | Expose internal data structures (e.g. [`AST`] nodes). Beware that Rhai internals are volatile and may change from version to version. | | `internals` | Expose internal data structures (e.g. [`AST`] nodes). Beware that Rhai internals are volatile and may change from version to version. |

View File

@ -432,7 +432,7 @@ impl Module {
/// let mut module = Module::new(); /// let mut module = Module::new();
/// let hash = module.set_raw_fn("double_or_not", /// let hash = module.set_raw_fn("double_or_not",
/// // Pass parameter types via a slice with TypeId's /// // Pass parameter types via a slice with TypeId's
/// &[std::any::TypeId::of::<i64>(), std::any::TypeId::of::<bool>() ], /// &[std::any::TypeId::of::<i64>(), std::any::TypeId::of::<bool>()],
/// // Fixed closure signature /// // Fixed closure signature
/// |engine, lib, args| { /// |engine, lib, args| {
/// // 'args' is guaranteed to be the right length and of the correct types /// // 'args' is guaranteed to be the right length and of the correct types