luameta-method

Lua __index method not executing on read


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)


Solution

  • 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)