Experienced metatables users, will this code cause performance issues?

Hello, so been trying to get changes made in a dictionary no matter how deep it is and finally got it to work but are there any downsides to the way I wrote this code?

function recursivemt(dict, path, root)
   root = root or dict
   local proxy = newproxy(true)
   local meta = getmetatable(proxy)
   path = path or ""

   meta.__index = function(self, index)
      local idx = dict[index]
      if idx and type(idx) == "table" then
         local newPath = path .. (path ~= "" and "." or "") .. tostring(index)
         idx = recursivemt(idx, newPath)
      end
      return idx
   end

   meta.__newindex = function(self, index, value)
      if dict[index] ~= value then
         dict[index] = value
         local fullPath = path .. (path ~= "" and "." or "") .. tostring(index)
         print('Change detected at path:', fullPath, 'to', value)
         setValueByPath(root, fullPath, value)
      end
   end

   return proxy
end

I am not really too experienced in OOP but this does look to be not very performant as you’re kind of runninga function in itself.

meta.__index = function(self, index)
      local idx = dict[index]
      if idx and type(idx) == "table" then
         local newPath = path .. (path ~= "" and "." or "") .. tostring(index)
         idx = recursivemt(idx, newPath)
      end
      return idx
   end

I might surely be wrong about this though.

Maybe try this?

1 Like

The thing is its insanely powerful though, I can detect changes in as many keys as my nested dictionary has so I think it depends on how just deep your table is, but thank you

If I’m correct then basically you create a proxy for the tables inside a dictionary every time it is indexed right ?

If that’s the case then it can be troublesome, you should simply instantiate the metatable upon creation (meaning the recursion should reside in the __newindex instead of __index)

I’m also unsure if you need to set the value using the ‘path’ value as assigning the dictionary’s children tables to a metatable directly will be adequate (Unless you’re trying to detect changes from a parent table)

1 Like