[LuaAPI] Using a metatable as an index??
Hi,
let's say I have...
lua_pushstring(L,"myarray");
lua_rawget(L,LUA_REGISTRYINDEX);
luaL_getmetatable(L,"whatever");
lua_rawget(L,-2);
where myarray = {} and whatever is a valid metatable. The final command confuses me. Is it looking for a table entry for the metatable index? If this index thus converted to a number or string?
lua_newtable(L);
luaL_getmetatable(L,name);
lua_pushvalue(L,-2);
lua_rawset(L,-4);
How about this?
Many Thanks
algorhythmic
You first code will do something like this:
- pushes "myarray" string on the stack
- rawget replaces the "myarray" stack entry with a value assigned to "myarray" key in the registry table
- getmetatable method won't work, because it doesn't accept string as an argument. The second argument should be a stack index of the table you want to get the metatable of. But since the only thing on a stack is myarray table, the only legal index is -1. This will push the metatable of myarray on the stack. If it is an empty table without any metatable assigned, it won't push anything and return 0.
- rawget is supposed to index myarray using it's metatable as a key. But if myarray has no metatable, it causes stack underflow, because there's only one item on the stack.
If you were trying to index a table with another table (or metatable, as long as it's represented by a regular table), nothing would be converted. This is a big power of tables in Lua - you can index them using any value / object. This is especially useful for creating unique keys. Like this:
uniquekey = { };
table[uniquekey] = something;
Your second code creates a new table. If "name" is -1 integer, the only valid stack index, it pushes the metatable of your new table, but since your new table doesn't have any metatable yet, it doesn't push anything. So the rest of the code is not valid.
- pushes "myarray" string on the stack
- rawget replaces the "myarray" stack entry with a value assigned to "myarray" key in the registry table
- getmetatable method won't work, because it doesn't accept string as an argument. The second argument should be a stack index of the table you want to get the metatable of. But since the only thing on a stack is myarray table, the only legal index is -1. This will push the metatable of myarray on the stack. If it is an empty table without any metatable assigned, it won't push anything and return 0.
- rawget is supposed to index myarray using it's metatable as a key. But if myarray has no metatable, it causes stack underflow, because there's only one item on the stack.
If you were trying to index a table with another table (or metatable, as long as it's represented by a regular table), nothing would be converted. This is a big power of tables in Lua - you can index them using any value / object. This is especially useful for creating unique keys. Like this:
uniquekey = { };
table[uniquekey] = something;
Your second code creates a new table. If "name" is -1 integer, the only valid stack index, it pushes the metatable of your new table, but since your new table doesn't have any metatable yet, it doesn't push anything. So the rest of the code is not valid.
Well for one the code must be correct as it's pulled straight from toLua. luaL_getmetatable takes a const char* name and a metatable for this name does exist.
This answers my question. What would be the best way of showing the content of table in text of diagram form?
Many Thanks
algorhythmic
Quote:If you were trying to index a table with another table (or metatable, as long as it's represented by a regular table), nothing would be converted. This is a big power of tables in Lua - you can index them using any value / object. This is especially useful for creating unique keys. Like this:
uniquekey = { };
table[uniquekey] = something;
This answers my question. What would be the best way of showing the content of table in text of diagram form?
Many Thanks
algorhythmic
Oh my yes, I have mitaken "lua_getmetatable" for "luaL_getmetatable". Sorry.
I looked at the source code of lauxlib.c:
So it just pushes a value of *tname string index in registry table. Too bad I don't have any documentation to the auxiliary library, I guess that's just helper function to store metatables in the registry...
To show contents of a table, I would do this:
However, this is only good for debugging purposes. It would be much harder to do some kind of a table serializator...
I looked at the source code of lauxlib.c:
LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) { lua_pushstring(L, tname); lua_rawget(L, LUA_REGISTRYINDEX);}
So it just pushes a value of *tname string index in registry table. Too bad I don't have any documentation to the auxiliary library, I guess that's just helper function to store metatables in the registry...
To show contents of a table, I would do this:
for k, v in table do print(tostring(k) .. " -> " .. tostring(v));end
However, this is only good for debugging purposes. It would be much harder to do some kind of a table serializator...
One last question, When going through the lua sources I noticed a few comments:
registry.name = metatable
and registry[metatable] = name
what's the difference between the . and the [] ?
I ask this in connection with luaL_newmetatable(L,name). Could you explain what it actually does?
Many Thanks
registry.name = metatable
and registry[metatable] = name
what's the difference between the . and the [] ?
I ask this in connection with luaL_newmetatable(L,name). Could you explain what it actually does?
Many Thanks
Why certainly!
table.index is the same as table["index"], that is, indexing using actual string "index"
table[index] is indexing using value of variable index
The table can be indexed with any value. Indexing using dot is just a syntax synonym for indexing using string constant. It is done this way to help programmers, so they don't have to write too much... indexing using string constants is widely used for representing data structures for example.
I don't know what luaL_newmetatable does; I don't use it. But I noticed it contains the two lines of yours, so I will try to explain them.
Let's say you have a metatable called "mt" (please note that a metatable doesn't need names, this is just a helper mechanism of the auxiliary library). The code assigns the actual metatable using it's name as an index and then assigns it's name using the metatable as an index. After that, if you have a metatable and want to retrieve it's name, you can do (in C API of course, in LUA you have no access to the registry table):
mtname = registry[mttable];
And when you know the name and want to obtain the metatable:
mttable = registry[mtname];
table.index is the same as table["index"], that is, indexing using actual string "index"
table[index] is indexing using value of variable index
The table can be indexed with any value. Indexing using dot is just a syntax synonym for indexing using string constant. It is done this way to help programmers, so they don't have to write too much... indexing using string constants is widely used for representing data structures for example.
I don't know what luaL_newmetatable does; I don't use it. But I noticed it contains the two lines of yours, so I will try to explain them.
Let's say you have a metatable called "mt" (please note that a metatable doesn't need names, this is just a helper mechanism of the auxiliary library). The code assigns the actual metatable using it's name as an index and then assigns it's name using the metatable as an index. After that, if you have a metatable and want to retrieve it's name, you can do (in C API of course, in LUA you have no access to the registry table):
mtname = registry[mttable];
And when you know the name and want to obtain the metatable:
mttable = registry[mtname];
Ok that certainly clears that up. Thanks. I just have difficulty seeing in what way the product of the luaL_newmetatable method is a metatable and not a standard table. I fail to see what makes the table it creates a metatable.
Metatables are standard tables. The only difference is that you define certain fields of it and assign it to another table. Be sure to check the Lua reference manual.
Yes I know this but at no point does the luaL_newmetatable method set the metatable so for all intents and purposes it's a normal table right? If that's the case then it's pretty misleading method name unless I'm missing something...
I think it's just an auxiliary mechanism for storing metatables using names. Of course you can use them as regular tables, but that would be pretty useless because IMHO if you want to store some table naming it, it would be a metatable for some kind of library written in Lua C API.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement