I'm trying to have my __index method fire anytime a key is read from this table, but it is apparently not firing since A) the contents read are never modified according to its intended math and B) its print statement never fires. What am I missing, please?
local scalar = 2
local scalar_template = {
__index = function(t, k)
print('hi?') --never fires
return rawget(t,k) * scalar
end
}
local m = {}
m.scalars = setmetatable({width = 2, height = 1, x = 10, y = 10}, scalar_template)
print(m.scalars.width) --2 rather than (2 * ui_scalar = 4)
scalar = 2.5
print(m.scalars.width) -- 2 rather than (2 * ui_scalar = 5)
You seem to have made a pretty common mistake, __index
is only called if the key being used does NOT have a value in the table you are indexing with it.
You need to make use of a blank table in the setmetatable
call and reference the actually table in the meta function. You often see this with "protected" or "read only" tables.
local scalar = 2
local protected = {width = 2, height = 1, x = 10, y = 10}
local scalar_template = {
__index = function(_, k)
print('hi?')
return protected[k] * scalar
end
}
local m = {}
m.scalars = setmetatable({}, scalar_template)
print(m.scalars.width) --2 rather than (2 * ui_scalar = 4)
scalar = 2.5
print(m.scalars.width) -- 2 rather than (2 * ui_scalar = 5)