Search code examples
lualua-tablemetatablemeta-method

attaching metatables within tabes


I have parser that parses a config file and produces a table.

The resulting table can look something like:

root = {
 global = {
 },
 section1 = {
   subsect1 = {
     setting = 1
     subsubsect2 = {
     }
   }
 }
}

The goal is to have a table I can read settings from and if the setting doesn't exist, it'll try to grab it from it's parent. At the top level it will grab from global. If it's not in global it'll return nil.

I attach metatables to root like this:

local function attach_mt(tbl, parent)
    for k,v in pairs(tbl) do
      print(k, v)
      if type(v) == 'table' then
        attach_mt(v, tbl)
        setmetatable(v, {
          __index = function(t,k)
            print("*****parent=", dump(parent))
            if parent then
              return tbl[k]
            else
              if rawget(tbl, k) then
                return rawget(tbl, k)
              end
            end
            print(string.format("DEBUG: Request for key: %s: not found", k))
            return nil
          end
        })
      end
    end
  end

  attach_mt(root)

However, when requesting keys it doesn't work. What appears to be the case is that is always nil. How do I read from the parent table?


Solution

  • local function attach_mt(tbl, parent)
       setmetatable(tbl, {__index = parent or root.global})
       for k, v in pairs(tbl) do
          if type(v) == 'table' then
             attach_mt(v, tbl)
          end
       end
    end
    attach_mt(root)
    setmetatable(root.global, nil)