I need some help with Lua metatables, specificaly with AutomagicTables (http://lua-users.org/wiki/AutomagicTables). The ability to just assign to undefined tables is very nice, and I would like to keep this functionality. My version has been placed in a single function:
require("dataentry") -- Contains my age function
function AutomagicTable()
-- Create a new data table
-- from https://lua-users.org/wiki/AutomagicTables
local auto, assign
function auto(tab, key)
return setmetatable({}, {
__index = auto,
__newindex = assign,
parent = tab,
key = key
})
end
local meta = {__index = auto}
function assign(tab, key, val)
if val ~= nil then
local oldmt = getmetatable(tab)
oldmt.parent[oldmt.key] = tab
setmetatable(tab, meta)
tab[key] = val
else
return nil
end
end
return setmetatable({}, meta)
end
What I want is to pass a table of defaults to be used when a field is not defined - as described in PIL Chapter 13 (https://www.lua.org/pil/13.4.3.html). This would allow calculated and lookup fields in my data strucutre. The following is the syntax I want to use:
t_defaults = {
Age = age(table["DOB"]),
Sex = "Female",
}
t = AutomagicTable(t_defaults)
t.ID12345.DOB = "7/2/1965"
t.ID12346.DOB = "1/2/1945"
print("ID12345",t.ID12345.Sex,t.ID12345.DOB,t.ID12345.Age)
print("ID12346",t.ID12346.Sex,t.ID12346.DOB,t.ID12346.Age)
Note the reference to the DOB field of the current table (see below) in this code age() fails as table["DOB"] is nil. If you run this code where there are no default values Automagic returns a table for the missing values.
I can assign defaults following the example in PIL Chapter 13, but the syntax is messy and once applied I loose the AutomagicTable functionality (as I have assigned a different metatable):
-- Make a metatables
t_defaults = {}
t_defaults.__index = function (table, key)
local def = {
Age = age(table["DOB"]),
Sex = "Female"
}
return def[key]
end
-- Set new metatable - but now we can't make anymore Automagic tables
setmetatable(t.ID12345, t_defaults)
setmetatable(t.ID12346, t_defaults)
-- This will work
print("ID12345",t.ID12345.Sex,t.ID12345.DOB,t.ID12345.Age)
print("ID12346",t.ID12346.Sex,t.ID12346.DOB,t.ID12346.Age)
-- This assignment fails
t.ID12347.DOB = "12/12/1945"
Unfortunately I don't fully understand the AutomagicTables code and am struggling to add the required functionality within the AutomagicTable code.
Any help gratefully received.
Gavin