Add oop.rhai script.

This commit is contained in:
Stephen Chung 2020-06-27 17:34:39 +08:00
parent d509006264
commit 549ef6bf7f
7 changed files with 62 additions and 3 deletions

View File

@ -37,7 +37,7 @@ Dynamic
* Dynamic dispatch via [function pointers]. * Dynamic dispatch via [function pointers].
* Some support for [OOP]. * Some support for [object-oriented programming (OOP)][OOP].
Safe Safe
---- ----

View File

@ -13,7 +13,8 @@ It doesn't attempt to be a new language. For example:
* No structures/records - define your types in Rust instead; Rhai can seamlessly work with _any Rust type_. * No structures/records - define your types in Rust instead; Rhai can seamlessly work with _any Rust type_.
There is, however, a built-in [object map] type which is adequate for most uses. There is, however, a built-in [object map] type which is adequate for most uses.
It is possible to simulate [OOP] by storing [function pointers] in [object map] properties, turning them into _methods_. It is possible to simulate [object-oriented programming (OOP)][OOP] by storing [function pointers]
in [object map] properties, turning them into _methods_.
* No first-class functions - Code your functions in Rust instead, and register them with Rhai. * No first-class functions - Code your functions in Rust instead, and register them with Rhai.

View File

@ -3,7 +3,7 @@ Special Support for OOP via Object Maps
{{#include ../links.md}} {{#include ../links.md}}
[Object maps] can be used to simulate object-oriented programming ([OOP]) by storing data [Object maps] can be used to simulate [object-oriented programming (OOP)][OOP] by storing data
as properties and methods as properties holding [function pointers]. as properties and methods as properties holding [function pointers].
If an [object map]'s property holds a [function pointer], the property can simply be called like If an [object map]'s property holds a [function pointer], the property can simply be called like

View File

@ -50,6 +50,7 @@ operate on object maps:
| `remove` | property name | removes a certain property and returns it ([`()`] if the property does not exist) | | `remove` | property name | removes a certain property and returns it ([`()`] if the property does not exist) |
| `+=` operator, `mixin` | second object map | mixes in all the properties of the second object map to the first (values of properties with the same names replace the existing values) | | `+=` operator, `mixin` | second object map | mixes in all the properties of the second object map to the first (values of properties with the same names replace the existing values) |
| `+` operator | first object map, second object map | merges the first object map with the second | | `+` operator | first object map, second object map | merges the first object map with the second |
| `fill_with` | second object map | adds in all properties of the second object map that do not exist in the object map |
| `keys` | _none_ | returns an [array] of all the property names (in random order), not available under [`no_index`] | | `keys` | _none_ | returns an [array] of all the property names (in random order), not available under [`no_index`] |
| `values` | _none_ | returns an [array] of all the property values (in random order), not available under [`no_index`] | | `values` | _none_ | returns an [array] of all the property values (in random order), not available under [`no_index`] |

View File

@ -20,6 +20,7 @@ There are also a number of examples scripts that showcase Rhai's features, all i
| [`function_decl3.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/function_decl3.rhai) | A [function] with many parameters | | [`function_decl3.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/function_decl3.rhai) | A [function] with many parameters |
| [`if1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/if1.rhai) | [`if`](#if-statement) example | | [`if1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/if1.rhai) | [`if`](#if-statement) example |
| [`loop.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/loop.rhai) | Count-down [`loop`](#infinite-loop) in Rhai, emulating a `do` .. `while` loop | | [`loop.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/loop.rhai) | Count-down [`loop`](#infinite-loop) in Rhai, emulating a `do` .. `while` loop |
| [`oop.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/oop.rhai) | Simulate [object-oriented programming (OOP)][OOP] |
| [`op1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op1.rhai) | Just simple addition | | [`op1.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op1.rhai) | Just simple addition |
| [`op2.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op2.rhai) | Simple addition and multiplication | | [`op2.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op2.rhai) | Simple addition and multiplication |
| [`op3.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op3.rhai) | Change evaluation order with parenthesis | | [`op3.rhai`](https://github.com/jonathandturner/rhai/tree/master/scripts/op3.rhai) | Change evaluation order with parenthesis |

45
scripts/oop.rhai Normal file
View File

@ -0,0 +1,45 @@
// This script simulates object-oriented programming (OOP) techniques
// using function pointers (Fn) and object maps.
// Define object
let obj1 = #{
_data: 42, // data field
get_data: Fn("getData"), // property getter
action: Fn("action"), // method
update: Fn("update1") // property setter
};
fn getData() {
this._data
}
fn action() {
print("Data=" + this._data);
}
fn update1(x) {
this._data = x;
this.action();
}
if obj1.get_data() > 0 { // property access
obj1.update(123); // call method
} else {
print("we have a problem here");
}
// Define another object based on the first object
let obj2 = #{
_data: 0, // data field - new value
update: Fn("update2") // property setter - another function
};
obj2.fill_with(obj1); // add all other fields from obj1
fn update2(x) {
this._data = x * 2;
this.action();
}
if obj2.get_data() > 0 { // property access
obj2.update(0); // call method
} else {
obj2.update(42); // call method
}

View File

@ -39,6 +39,17 @@ def_package!(crate:BasicMapPackage:"Basic object map utilities.", lib, {
Ok(()) Ok(())
}, },
); );
lib.set_fn_2_mut(
"fill_with",
|map1: &mut Map, map2: Map| {
map2.into_iter().for_each(|(key, value)| {
if !map1.contains_key(key.as_str()) {
map1.insert(key, value);
}
});
Ok(())
},
);
lib.set_fn_2_mut( lib.set_fn_2_mut(
"+=", "+=",
|map1: &mut Map, map2: Map| { |map1: &mut Map, map2: Map| {