Search code examples
luametatable

How to use metatables to monitor changes made to an embedded table? (Lua)


I am looking to monitor changes made to one particular embedded table, in this case oranges, using the __newindex metamethod. My current code is able to detect the change, yet the value will obviously not update. I understand that the original data needs a proxy table in order to use the __newindex metamethod for detecting value changes.

local data = {cherries = {quantity = 0}, oranges = {quantity = 0}}
local _data = data
data.oranges = {}

local metaTable = {
    __newindex = function (_, key, value)
        print("Updating " .. tostring(key) .. " to " .. tostring(value))
        _data[key] = value
    end
}

setmetatable(data.oranges, metaTable)

data.oranges.quantity = 1 -- Invokes "Updating quantity to 1"
print(data.oranges.quantity) -- "nil" (I would like it to print 1)

Solution

  • You need to set an index metamethod:

    local metaTable = {
        __newindex = function (_, key, value)
            print("Updating " .. tostring(key) .. " to " .. tostring(value))
            _data[key] = value
        end,
        __index = function (_, key, value)
            return data[key]
        end
    }