Iterating over pseudo (meta) tables...

Posted by RasmusKL on Mon 08 Jan 2007 03:19 PM — 3 posts, 19,015 views.

#0
I'm trying to make a transparant metatable, this is easy enough to do with the meta-methods __index and __newindex, however, iterating over this table is giving me some problems...

Is it possible to make this work... That is, I know the list of "meta"-indices that I want to have in the table - and want ipairs / pairs to iterate over this list.

Right now, using


for x, y in pairs(pseudo_table) do 
  print(x) 
end 


gives nothing, since I have no where to put the list..

If we consider Nick's usage of metatables to access MushClient variables using __index and __newindex, this would be equivalent to being able to iterate over all the variables - doing another workaround to make


for k, v in pairs(var) do
  Note (k, " = ", v) 
end


be equivalent to:


for k, v in pairs(GetVariableList()) do 
  Note (k, " = ", v) 
end


My best work-around so far has been to use the __call metamethod and returning the list there, but this is error-prone - and it's non-intuitive to people who aren't aware of the table being a "pseudo" table. The result looking something like:


for k, v in pairs(var()) do 
  Note (k, " = ", v) 
end


Any bright ideas? :-)

Thanks,
- Rasmus.


Amended on Mon 08 Jan 2007 03:20 PM by RasmusKL
#1
Hmm,

thinking further about the problem, one way I could solve it is to redefine the pairs function, but this still gives problems if people use foreach etc.


local oldpairs = pairs
function pairs(t)
  if t.__indices then
    return t.__indices
  end
  
  return oldpairs(t)
end


Meh, still not all that happy about it :-)

- Rasmus.
Australia Forum Administrator #2
One of the side-effects of making proxy tables which catch attempts to access the contents via __index and __newindex is that the table will simply not behave as a normal table when you use pairs (or ipairs) because it is empty.

I don't think there is a simple workaround for that. The closest I think you could come, for the case of the MUSHclient var table, is to write your own iterator function, which is specifically used for that table.

However I think that this code snippet (from GetVariableList description) does the same thing and is pretty straightforward:


-- show all variables and their values

for k, v in pairs (GetVariableList()) do 
  Note (k, " = ", v) 
end


This code below does what I suggest and thus saves a small amount of code:



-- function to make iterator function for var table:
function varPairs ()
  return pairs (GetVariableList())
end -- varPairs 


-- test it:
for k, v in varPairs () do
  print (k, v)
end