I have a Java Class with a method called test:
public class MyClass() {
public String test() {
//Do Something
}
}
Then, I want to call the test method in my Lua script. In order to do it, I did:
Globals globals = JsePlatform.standartGlobals();
LuaValue test = CoerceJavaToLua.coerce(new MyClass());
globals.set("obj", test);
LuaValue chunk = globals.load("obj.test()");
chunk.call();
When the Lua script is called, I got a bad argument error.
It only works when I use "obj:test()".
It's like I should pass the object in the first parameter.
Is there a way to do "obj.test()" work?
I can't find any examples of binding a static function of a class and calling it without an instance of the class. All examples everywhere, even when using static functions, pass an instance of the object. Thus I can not be 100% sure this is not possible to do (without editing luaj).
Any static functions in libraries and examples are actually made with creating a dummy class for example see here http://luaj.cvs.sourceforge.net/viewvc/luaj/luaj-vm/examples/jse/hyperbolic.java?view=markup
A closer look at the luaj source shows that luaj does not distinct between static and nonstatic functions in a class which means all are handled as nonstatic. See JavaClass.java
getMethod
function for more.
Here is a rather simple example how you can accomplish what you wanted, but sadly it requires to not have a static method.
package luaj;
import org.luaj.vm2.*;
import org.luaj.vm2.lib.*;
import org.luaj.vm2.lib.jse.*;
public class luaj {
static final public class MyClass {
public static int asd = 5;
static public class Test extends ZeroArgFunction {
@Override
public LuaValue call() {
System.out.println("Worked");
return NIL;
}
}
}
public static void main(String[] args) {
Globals globals = JsePlatform.standardGlobals();
LuaValue test = CoerceJavaToLua.coerce(new MyClass());
globals.set("obj", test);
LuaTable t = new LuaTable();
t.set("test", new MyClass.Test());
t.set("__index", t);
test.setmetatable(t);
LuaValue chunk = globals.load("print('Testing', obj.asd) obj.test()");
chunk.call();
}
}
A similar approach can probably be done with using a static method by setting obj.test
to a function that wraps the real obj.test
and passes a new instance of MyClass
to it thus "hiding" the passing of an instance.