I want to set extra "methods" to some tables that are in some lua_State.
The state has the code like this:
obj = {}
function obj:method1()
print("value from second method = " .. self.method2())
end
I load it by do_file() method. After this I want to add method2() to the table obj. This method2() must get on the stack the table obj (as self) to work properly.
I'm trying to do it like this:
state.get_global("obj");
if state.is_table(-1) {
state.push_string("method2");
state.push_fn(Some(method2));
state.set_table(-3);
}
or in C:
lua_getglobal(L, "obj");
if (lua_istable(L, -1)) {
lua_pushstring(L, "method2");
lua_pushcfunction(L, &lua_method2);
lua_settable(L, -3);
}
The method2() function is written okay, same functions I use for "new_lib" and they work good.
When I do all that, in method2() I check:
if (lua_istable(L, -1)) {
// Do some work
} else {
print("not a table!");
}
And I get "not a table" instead of actual work.
How can I do such a thing? And will the method2() in Rust(C/C++, whatever) get obj table (self) as first parameter on a stack?
If you have a table T
and you call T:Func()
and T.Func
is any function, then T
will be the first parameter in the method call.
So if in your code you call obj:method2()
then obj
will be the first parameter.
Note that you should call the function with the :
operator like so obj:method2()
. If you call it with .
operator then you need to pass the obj table to the method or you run into the same nil error you have mentioned since there are no arguments passed in that case. The :
operator is just a syntactic sugar for obj.method2(obj)
.
I would also try use lua_istable(L, 1)
since the arguments are at the bottom of the stack. If someone calls obj:method2(2)
then the method would fail because top of the stack has a number value and not a table.
The stack is cleared for a function call so the arguments passed are always at the very bottom of the stack.
Btw. in the C code of yours you are missing the push for the function name.