this
– Simulating an Object Method
The only way for a script-defined function to change an external value is via this
.
Arguments passed to script-defined functions are always by value because functions are pure.
However, functions can also be called in method-call style:
object
.
method(
parameters …)
When a function is called this way, the keyword this
binds to the object in the method call and
can be changed.
fn change() { // note that the method does not need a parameter
this = 42; // 'this' binds to the object in method-call
}
let x = 500;
x.change(); // call 'change' in method-call style, 'this' binds to 'x'
x == 42; // 'x' is changed!
change(); // <- error: 'this' is unbound
Elvis Operator
The Elvis operator can be used to short-circuit the method call when the object itself is ()
.
object
?.
method(
parameters …)
In the above, the method is never called if object is ()
.
Bind to this
for Module Functions
The method-call syntax is not possible for functions imported from modules.
import "my_module" as foo;
let x = 42;
x.foo::change_value(1); // <- syntax error
In order to call a module function as a method, export that method as a
function pointer and use the call
syntax:
┌────────────────┐
│ my_module.rhai │
└────────────────┘
// The actual function that uses 'this'
private fn change_value_impl(offset) {
this += offset;
}
// Export it as a function pointer
export const change_value = change_value_impl;
// The above is equivalent to:
export const change_value = Fn("change_value_impl");
// Or do it in one step via a closure
export const change_value = |offset| this += offset;
┌───────────┐
│ main.rhai │
└───────────┘
import "my_module" as foo;
let x = 42;
// Use 'call' to bind 'x' to 'this'
x.call(foo::change_value, 1);
x == 43;