Automagic Tables |
|
a = AutomagicTable()
a.b.c.d = "a.b and a.b.c are automatically created"
This version was the result of several interesting interchanges between ThomasWrensch and me (RiciLake), and I cannot take credit for it (although I am happy to take the blame; I've made a couple of modifications and changed the formatting because I like spaces in parameter lists)
do local auto, assign function auto(tab, key) return setmetatable({}, { __index = auto, __newindex = assign, parent = tab, key = key }) end local meta = {__index = auto} -- The if statement below prevents the table from being -- created if the value assigned is nil. This is, I think, -- technically correct but it might be desirable to use -- assignment to nil to force a table into existence. function assign(tab, key, val) -- if val ~= nil then local oldmt = getmetatable(tab) oldmt.parent[oldmt.key] = tab setmetatable(tab, meta) tab[key] = val -- end end function AutomagicTable() return setmetatable({}, meta) end end
[*] There is a Lua 4 version of this as well, but it is not as tidy.
I think the technique above -- the use of an individualized metatable with additional non-metamethod keys -- is more than just a handy trick.
If you want to associate some information with a table you have three choices:
The problem with the first trick is it may conflict with an existing key and/or pollute the table with inappropriate data. You pointed out some of the problems with the second approach in your message (on GarbageCollectingWeakTables) a while ago. The third requires the use of an individual metatable, but does not have the problems of the other two techniques.