[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Make type respect __name and add rawtype
- From: DarkWiiPlayer <darkwiiplayer@...>
- Date: Thu, 24 Dec 2020 11:38:19 +0100
Greetings Lua-l!
A while ago I was having a look at the Lua source code and found that in
certain parts, a `__name` value in the metatable is used for providing
custom type names to objects.
I've held the opinion for years now that there should be a way to change
what type is reported for an object by the `type` function, so I took
the opportunity that most of this is already implemented and wrote a
quick patch that adds this behavior, along with a `rawtype` function
that essentially works as the `type` function normally does.
I posted the patch on github for easier reading, but I'm also appending
it at the bottom of the mail:
https://gist.github.com/DarkWiiPlayer/bb0d153827990b4781f4f743d2bc7a3a
I will admit that I didn't spend much time considering the performance
impact of such a change, but I imagine for most Lua code it would make
almost no difference.
While it would be a breaking change, the only code that would be
affected is where the `__name` field is already being used for something
else, which I doubt would be in too many places.
As an alternative proposal: if changing the behavior of `type` is
considered a bad idea, I'd love to at least see some other function that
behaves like this, although I'm unsure about what it could be called.
`type` really is the best name in my opinion, with `name` (in reference
to the `__name` field name) being the next best option I can think of.
`class` might also be easy to remember for non-programmers, but
misleading to people with a programming background. The only other thing
I can think of is `typename`, which is probably the easiest to remember
(Does what `type` does, except when `__name` exists).
Greetings and happy holidays!
—————
diff --unified -r lua-5.4.0/src/lapi.c lua-5.4.0-rawtype/src/lapi.c
--- lua-5.4.0/src/lapi.c 2020-06-18 16:25:53.000000000 +0200
+++ lua-5.4.0-rawtype/src/lapi.c 2020-11-27 09:31:30.787330086 +0100
@@ -267,6 +267,13 @@
}
+LUA_API const char *lua_objtypename (lua_State *L, int t) {
+ api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type");
+ const TValue *o = index2value(L, t);
+ return luaT_objtypename(L, o);
+}
+
+
LUA_API int lua_iscfunction (lua_State *L, int idx) {
const TValue *o = index2value(L, idx);
return (ttislcf(o) || (ttisCclosure(o)));
diff --unified -r lua-5.4.0/src/lbaselib.c lua-5.4.0-rawtype/src/lbaselib.c
--- lua-5.4.0/src/lbaselib.c 2020-06-18 16:25:53.000000000 +0200
+++ lua-5.4.0-rawtype/src/lbaselib.c 2020-11-27 09:38:19.813573132 +0100
@@ -240,7 +240,7 @@
}
-static int luaB_type (lua_State *L) {
+static int luaB_rawtype (lua_State *L) {
int t = lua_type(L, 1);
luaL_argcheck(L, t != LUA_TNONE, 1, "value expected");
lua_pushstring(L, lua_typename(L, t));
@@ -248,6 +248,16 @@
}
+static int luaB_type (lua_State *L) {
+ int t = lua_type(L, 1);
+ luaL_argcheck(L, t != LUA_TNONE, 1, "value expected");
+ //lua_pushstring(L, lua_typename(L, t));
+ const char *s = lua_objtypename(L, -1);
+ lua_pushstring(L, s);
+ return 1;
+}
+
+
static int luaB_next (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
@@ -504,6 +514,7 @@
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
+ {"rawtype", luaB_rawtype},
{"xpcall", luaB_xpcall},
/* placeholders */
{LUA_GNAME, NULL},
diff --unified -r lua-5.4.0/src/lua.h lua-5.4.0-rawtype/src/lua.h
--- lua-5.4.0/src/lua.h 2020-06-18 16:25:54.000000000 +0200
+++ lua-5.4.0-rawtype/src/lua.h 2020-11-27 09:33:22.347601208 +0100
@@ -186,6 +186,7 @@
LUA_API int (lua_isuserdata) (lua_State *L, int idx);
LUA_API int (lua_type) (lua_State *L, int idx);
LUA_API const char *(lua_typename) (lua_State *L, int tp);
+LUA_API const char *(lua_objtypename) (lua_State *L, int tp);
LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int
*isnum);
LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int
*isnum);