Hi just wanted to hear opinions on something I came up with to deal with elements in a sparse very deep table (in practical terms this happens to me with saved variables). For example, if I want to access a[3][7]["aa"][2][2], I need to first check if a, a[3], a[3][7], a[3][7]["aa"] and a[3][7]["aa"][2] exist, otherwise I would get an "attempt to index 'a' (a nil value)". With the following metamethods I can just:
Lua Code:
local a = new_table()
print(a(3,7,"aa",2,2)) --this prints nil as it should (since value was not set) but no errors
a[3][7]["aa"][2][2] = "zzz" --sets everything in the path not set already: a[3], a[3][7], a[3][7]["aa"] etc
print(a(3,7,"aa",2,2)) --this prints "zzz"
The only problem I can see is that you must use the proper forms depending if you are reading or writting, for example:
Lua Code:
local b = new_table()
print(b[1][1][1]) --instead of printing nil, this is the same as b[1]=new_table() b[1][1]=new_table() b[1][1][1]=new_table() and will print b[1][1][1] address (an empty table with a metatable attached)
b(1,1,1) = "rrr" --this will not run: syntax error near '='
But I couldn't find a way to do both things (read and write) with the same format. Sorry if this sounds too trivial but it sounded like an Eureka! moment to me.
Lua Code:
local mt = {}
mt["__index"] = function(t,k)
local v = setmetatable({},mt)
rawset(t,k,v)
return v
end
mt["__call"] = function(t,...)
local i,n,v = 1,select("#",...),{...}
while t and i<=n do
t = rawget(t,v[i])
i = i+1
end
return t
end
local new_table = function()
return setmetatable({},mt)
end
How good do you think this is?