Lua: дать пользовательским данным метод tostring

У меня есть пользовательские данные в Луа. Когда я выполню 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;
}

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;
}
4

Другие решения

Вам придется переопределить tostring так что он проверяет, является ли значение одним из его пользовательских типов. Если это так, используйте вашу собственную функцию, чтобы получить имя. Если нет, передайте его переопределенному tostring, Обычно это делается путем помещения оригинала tostring в повышении, а затем заменить глобальный tostring с этим.

0

По вопросам рекламы [email protected]