The following example creates a userdatatype value MyType, and the table is created using the metafunction __tostringthat invokes LI_MyType__tostring. Code creates a LOP OOP based on closure. My problem with the provided example looks as if there is only one way to associate userdatawith a method call through upvalues. This in itself is not a problem if I do not want to use the same metatet between instances.
In an ideal world - and what do I hope to find in this question - is there a way to associate an upvalue value with a value (for example userdata) without associating it with a function call through an upvalue? I hope there is a trick that will allow me to continue to use loo OOP based on closure and use the same metatet for different instances. I am not an optimist, but I decided that I would ask to see if anyone has a suggestion or an unobvious trick.
using FuncArray = std::vector<const ::luaL_Reg>;
static const FuncArray funcs = {
{ "__tostring", LI_MyType__tostring },
};
int LC_MyType_newInstance(lua_State* L) {
auto userdata = static_cast<MyType*>(lua_newuserdata(L, sizeof(MyType)));
new(userdata) MyType();
lua_createtable(L, 0, funcs.size());
lua_pushvalue(L, -2);
luaL_setfuncs(L, funcs.data(), 1);
lua_setmetatable(L, -2);
return 1;
}
int LI_MyType__tostring(lua_State* L) {
const auto n = lua_upvalueindex(1);
lua_pushvalue(L, n);
auto myTypeInst = static_cast<MyType*>(lua_touserdata(L, -1));
lua_pushstring(L, myTypeInst->str());
return 1;
}
I hope there is a way to accomplish something like this (this is pseudo code!):
int LI_MyType__tostring(lua_State* L) {
const int stackPosition = -1;
const int upvalueIndex = 1;
const auto n = lua_get_USERDATA_upvalue(L, stackPosition, upvalueIndex);
lua_pushvalue(L, n);
auto myTypeInst = static_cast<MyType*>(lua_touserdata(L, -1));
lua_pushstring(L, myTypeInst->str());
return 1;
}
I know this looks like everything will be for the βnormalβ metatable OOP style, but I want things to close and not introduce a colon syntax.
: userdata ? lua , , , -, .
UPDATE (2013-10-10): @lhf lua_setuservalue() lua_getuservalue() :
- ,
luaL_newmetatable(). metatable userdata, . userdata (lua_newuserdata()).- metatable
userdata (lua_setmetatable()). - / upvalue,
userdata. lua_setuservalue() userdata / .- (,
__index), userdata uservalue.
:
- upvalues ββ
- upvalues ββ .
- / , . , obj.myMethod() obj function myMethod() - :, , :, - ( upvalue).