Closed justinpombrio closed 3 months ago
Yes this seems to be a bug.
The reason: closures are actually syntactical sugar for function calls with capturing. So the script:
|| state // 'state' is captured from outer scope here
is compiled into:
fn anon_fn(state) { state } // the closure body
make_shared(state); // make the 'state' variable shared
Fn("anon_fn").curry(state); // curry it into the function pointer
So in reality state
exists within the function as a parameter. The make_shared
operation, however, should respect the on_var
callback, which it obviously doesn't.
This is a relatively simple fix. Do you need this fix urgently? If so, I can release 1.18.1
... otherwise you can pull from this repo until 1.19.0
comes out...
Do you need this fix urgently?
Nope! We got our test case working with a Rhai module and FuncRegistration instead. We might (or might not) eventually switch to on_var instead, but not at all urgent.
Thanks for the quick response!
Thanks. The fix has landed here. You can pull from this repo to try it out.
Confirmed fixed!
Closing this for now. Feel free to reopen if there are further problems.
The
on_var
callback seems to not be invoked for variables that appear in closures.Rhai version: 1.18.0
Input
Expected: the
on_var
callback to be invoked in all three cases.Actual: the
on_var
callback is not invoked for the closure, resulting in a "variable not found" error.Comments: This makes
on_var
ineffective for our use case. Our goal is to expose a single global "runtime" for use everywhere. User written scripts should be able to access methods likeruntime.do_thing()
anywhere in any script. Here's what we've tried overall:runtime
as aRc<RefCell<Runtime>>
in aScope
. This makesruntime
inaccessible inside Rhaifn
s, though, as documented.runtime
as aRc<RefCell<Runtime>>
inserted viaEngine.on_var()
. This makesruntime
inaccessible inside Rhai closures (this issue).The final thing we'll try (if this issue isn't fixable) is to bind every method on
Runtime
as a function in Rhai. But wrap them all in a module, so that they're not all spilled into the global namespace (there may be hundreds of them all told).