Issue with iterating through values with metatables
Hi,
I don't know exactly how the pairs, ipairs, and next iterator functions in Lua work, only what they do but still I thought they have to access index's of a table but they seem to have strange results on metatable's which is very annoying to work with: Lua Code:
or: Lua Code:
These test examples show my point. Both ipairs and pairs, no matter what is in the "realTable" (index/value pairs or key/value pairs) will never access the meta method __index to go to the realTable. I can sort of understand why pairs will not work but ipairs tries to access the first index [1] of someTable which does not exist so shouldn't it attempt to call the __index meta method? Also if I replace pairs/ipairs with the "next" function I get an "attempt to call a nil value" Lua error instead which seems even more strange to me. I understand that pairs does not directly look for "aValue" in the someTable but is it possible to achieve the result of looking inside the realTable instead using these iterator functions as a way around this? Thanks for reading :) EDIT: I have read the documentation from lua.org about how ipairs works and still cannot understand why the __index method is not triggered: Quote:
Shouldn't line "local v = a[i]" call this method? Because this should equivalate to "local v = someTable[i]" which is an attempt to access an index which does not exist in someTable which should mean it calls __index to check the realTable instead. But it doesn't do this! :( _ |
I don't know, but, this stuff makes my head hurt. :rolleyes: :o
|
I'm just not sure what are you trying to accomplish, for me it's seems like you are creating an empty metatable.
If you change your code like this, then it should work: Lua Code:
|
Quote:
Because basically I want the __index function to ALWAYS trigger so to do this I use __newindex to add entries to the parent table rather than the normal table so every time a value is indexed using the normal table, it has to use the __index function which returns the value from the parent table, as well as perform other stuff. Here's an abbreviated example of the real code I am working on: Lua Code:
|
Quote:
http://www.lua.org/pil/13.4.4.html |
Your sometable table doesn't have anything in it, that's why your pairs() loop doesn't see anything. If you were actually trying to index something (doing sometable[key] or sometable.key) and the key does not exist in your table, *that's* when it will look it up in the __index in the metatable to get a value.
In my experience, metatables work better with key=value pairs, rather than an "array"-type table (with numerical indices). Though I don't know how you're constructing your table... Here's where it can go wrong: Lua Code:
Okay, so then if you do this... Lua Code:
Where did "a" go? |
Quote:
Quote:
|
Quote:
But I do understand how the __Index method works and how it looks at the original table before looking at the "inherited" one :) I just wish that for loop iterator functions would trigger the __index method when it tries to index something that does not exist in the original table but from reading the link Resike sent I just have to assume its impossible. |
Quote:
|
Quote:
But thanks, I may just do that :) I'm basically rewriting my entire UI from scratch with a better framework that supports functions to be used for my UI in a much nicer, organised structure. But I thought it would be nice for me and others if pairs and ipairs could traverse all the different functions etc.. that are stored in my library/API tables. I've documented it all nicely so the only way to notice that they actually exist is to read the .lua files which I guess will have to do :) But making my own pairs function will help me program much easier so that's one problem solved! |
pairs() and ipairs() functions don't perform any Lua indexing operations. They're C-side code that iterate through the indexed and hash arrays that make up any table within Lua's C code. If there's nothing in those C arrays, nothing happens. Metatables are something else entirely and don't touch the C arrays of the tables they're assigned to.
In essence, if you make a blank table and iterate though it, you get nothing. It doesn't matter if there's a metatable assigned or not. If you really need to iterate though the metatable, you can do so, but it's considered its own table. Code:
for k,v in pairs(getmetatable(t).__index) do Though, if your intent were to expose the metatable functions as an API, it's best to make the functions as API first, then link them into a metatable rather than the other way around. Code:
function DoSomething(t,val) |
Thanks a lot! That Lua.org page just confused me then showing the pairs and ipairs functions as Lua code. I may try the approach you recommended. It sounds much easier :)
|
All times are GMT -6. The time now is 07:46 AM. |
vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI