rhai/doc/src/patterns/oop.md

62 lines
2.1 KiB
Markdown
Raw Normal View History

2020-06-26 04:39:18 +02:00
Object-Oriented Programming (OOP)
================================
{{#include ../links.md}}
Rhai does not have _objects_ per se, but it is possible to _simulate_ object-oriented programming.
Use [Object Maps] to Simulate OOP
--------------------------------
Rhai's [object maps] has [special support for OOP]({{rootUrl}}/language/object-maps-oop.md).
| Rhai concept | Maps to OOP |
| ----------------------------------------------------- | :---------: |
| [Object maps] | objects |
| [Object map] properties holding values | properties |
| [Object map] properties that hold [function pointers] | methods |
2020-07-19 11:14:55 +02:00
When a property of an [object map] is called like a method function, and if it happens to hold
2020-08-07 12:40:31 +02:00
a valid [function pointer] (perhaps defined via an [anonymous function] or more commonly as a [closure]),
then the call will be dispatched to the actual function with `this` binding to the [object map] itself.
2020-06-26 04:39:18 +02:00
2020-07-29 16:43:57 +02:00
Use Anonymous Functions to Define Methods
----------------------------------------
2020-08-07 12:40:31 +02:00
[Anonymous functions] or [closures] defined as values for [object map] properties take on
a syntactic shape that resembles very closely that of class methods in an OOP language.
2020-07-29 16:43:57 +02:00
2020-08-07 12:40:31 +02:00
Closures also _[capture][automatic currying]_ variables from the defining environment, which is a very
2020-07-29 16:43:57 +02:00
common OOP pattern. Capturing is accomplished via a feature called _[automatic currying]_ and
2020-08-03 06:10:20 +02:00
can be turned off via the [`no_closure`] feature.
2020-07-29 16:43:57 +02:00
2020-06-26 04:39:18 +02:00
Examples
--------
```rust
2020-08-03 06:10:20 +02:00
let factor = 1;
2020-06-26 04:39:18 +02:00
// Define the object
2020-08-07 12:40:31 +02:00
let obj = #{
data: 0, // object field
increment: |x| this.data += x, // 'this' binds to 'obj'
update: |x| this.data = x * factor, // 'this' binds to 'obj', 'factor' is captured
action: || print(this.data) // 'this' binds to 'obj'
};
2020-06-26 04:39:18 +02:00
// Use the object
obj.increment(1);
2020-08-07 12:40:31 +02:00
obj.action(); // prints 1
2020-08-03 06:10:20 +02:00
obj.update(42);
2020-08-07 12:40:31 +02:00
obj.action(); // prints 42
2020-08-03 06:10:20 +02:00
factor = 2;
2020-06-26 04:39:18 +02:00
obj.update(42);
2020-08-07 12:40:31 +02:00
obj.action(); // prints 84
2020-06-26 04:39:18 +02:00
```