How to retain chaiscript evaluation context


#1

This code:

#include <iostream>
#include <chaiscript/chaiscript.hpp>
#include <chaiscript/dispatchkit/bootstrap.hpp>
#include <chaiscript/chaiscript_stdlib.hpp>

using fun = std::function<void()>;
struct Something
{
    Something():chai(chaiscript::Std_Lib::library())
    {
        chai.add(chaiscript::fun(&Something::SetFunc, this), "set_func");
        chai.eval(R"(
                var a = 0
                def f()
                {
                    print(a)
                }
                set_func(f)
                )");
    }

    void SetFunc(fun f)
    {
        Func = std::move(f);
    }

    void Do()
    {
        Func();
    }

    chaiscript::ChaiScript chai;
    fun                        Func;
};

int main()
{
    try
    {
        Something s;
        s.Do();
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << "\n";
    }
}

This produce : Error: "Can’t find object : a"
So it looks like when the function f is called through std::function, variable a is already destroyed. Is there a way to extend the lifespan of a ? Or is this just impossible in chaiscript ?


#2

Variable a is alive and well, it’s just in the top level scope and not visible to your function. In other words - you’re attempting to access a non-global variable from inside of a function, which isn’t allowed. You have a few options:

def f(v) {
  print(v);
}

set_func(fun[a](){ f(a); }) // lambda with capture, similar to C++, 
                            // but the capture is by-reference here

or

global a = 0; // make a global so f can see it
def f()
{
  print(a);
}