Search code examples
javalualuaj

Luaj attempt to index ? (a function value)


I am trying to compile Lua code that has two functions which I want to invoke and get some information from but when I use invokemethod on the LuaValue object, I get this error

LuaError: attempt to index ? (a function value)

The code is inside a LuaScript class I created for convenience

This method is first called to compile the file

public void compile(File file) {
    try {
        Globals globals = JmePlatform.standardGlobals();
        compiledcode = globals.load(new FileReader(file), "script");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

And then this is used to invoke the function getSameTiles from my lua script

public Object invoke(String func, Object... parameters) {
    if (parameters != null && parameters.length > 0) {
        LuaValue[] values = new LuaValue[parameters.length];
        for (int i = 0; i < parameters.length; i++)
            values[i] = CoerceJavaToLua.coerce(parameters[i]);
        return compiledcode.invokemethod(func, LuaValue.listOf(values));
    } else
        return compiledcode.invokemethod(func);
}

The error LuaError: attempt to index ? (a function value) occurs at the line return compiledcode.invokemethod(func); where "getSameTiles" is passed as the string for func

This is my Lua code

function getSameTiles()
    --My code here
end

Solution

  • There are a couple of issues that needed fixing.

    Firstly, in lua, load() returns a function which you'd then need to call to execute the script.

    Secondly, what the script does is add a function to the global table _G. In order to invoke that function you'll need to get the function from the Globals table and call that.

    The following code does this

    Globals globals = JmePlatform.standardGlobals();
    
    public void compile(File file) {
        try {
            globals.load(new FileReader(file), "script").call();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    public Object invoke(String func, Object... parameters) {
        if (parameters != null && parameters.length > 0) {
            LuaValue[] values = new LuaValue[parameters.length];
            for (int i = 0; i < parameters.length; i++)
                values[i] = CoerceJavaToLua.coerce(parameters[i]);
            return globals.get(func).call(LuaValue.listOf(values));
        } else
            return globals.get(func).call();
    }