Jump to content
  • Advertisement
Sign in to follow this  
algorhythmic

[LuaAPI] Using a metatable as an index??

This topic is 5112 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.
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

Share this post


Link to post
Share on other sites
Oh my yes, I have mitaken "lua_getmetatable" for "luaL_getmetatable". Sorry.

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...

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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];

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!