У меня есть пользовательские данные в Луа. Когда я выполню tostring
для экземпляра userdata (внутри Lua) он всегда возвращает строку типа "userdata: 0xaddress"
, Я хотел бы, чтобы он возвращал имя userdata ("Point: 0xaddress"
), что означает, что я хочу переопределить tostring
включить случай для моих пользовательских данных. Кто-нибудь знает, можно ли это сделать?
#define check_point(L) \
(Point**)luaL_checkudata(L,1,"Point")
static int
luaw_point_getx(lua_State* L)
{
Point** point_ud = check_point(L);
lua_pushinteger(L, (*point_ud)->x);
return 1;
}
static int
luaw_point_gety(lua_State* L)
{
Point** point_ud = check_point(L);
lua_pushinteger(L, (*point_ud)->y);
return 1;
}
void
luaw_point_push(lua_State* L, Point* point)
{
Point** point_ud = (Point**)lua_newuserdata(L, sizeof(Point*));
*point_ud = point;
luaL_getmetatable(L, "Point");
lua_setmetatable(L, -2);
}
static const struct luaL_Reg luaw_point_m [] = {
{"x", luaw_point_getx},
{"y", luaw_point_gety},
{NULL, NULL}
};
int
luaopen_wpoint(lua_State* L)
{
luaL_newmetatable(L, "WEAVE.Point");
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
luaL_register(L, NULL, luaw_point_m);
return 1;
}
Вы должны предоставить __tostring
метаметод, так же, как вы написали __index
,
// [...]
int luaw_point_index(lua_State* L)
{
lua_pushfstring(L, "Point: %p", lua_topointer(L, 1));
return 1;
}
int luaopen_wpoint(lua_State* L)
{
luaL_newmetatable(L, "WEAVE.Point");
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, luaw_point_index);
lua_setfield(L, -2, "__tostring");
luaL_register(L, NULL, luaw_point_m);
return 1;
}
Вам придется переопределить tostring
так что он проверяет, является ли значение одним из его пользовательских типов. Если это так, используйте вашу собственную функцию, чтобы получить имя. Если нет, передайте его переопределенному tostring
, Обычно это делается путем помещения оригинала tostring
в повышении, а затем заменить глобальный tostring
с этим.