Detecting when an item is added/removed to an array

Hi. I am currently trying to use metatables to detect when a new item is added/removed to an array. I have tried this following code but it does not work:

local t = setmetatable({}, {
	__newindex = function(tab,ind,val)
		print("New index")
	end
})

table.insert(t, "hello") -- doesnt print "New index"

I’m not too sure if this is even is possible in lua, and I have been stuck on this for a while. The only other option I know is just using a while loop to check if its length had changed, which is something I would like to avoid doing.

1 Like

I think it’s because table.insert uses rawset which bypasses the __newindex metamethod.

Try just manually setting it

local t = setmetatable({}, {
	__newindex = function(tab,ind,val)
		print("New index")
		rawset(tab,ind,val)
	end
})

t[#t+1] = "hellooo2"
print(t)
local function insert(t, val)
	t[#t+1] = val
end
4 Likes

If your going to use a insert function would it not be better to just detect inside the function instead of using a metatable?

local t = {}

local function Set(key, value)
    t[key] = value
    print("New Index", key, value)
end

-- Insert
Set(#t + 1, "Hello")

-- Remove
Set(#t, nil)
3 Likes

Very true. And on a side note, __newindex will not invoke when changes occur to the same key-value pair. So if you’re using rawset like in the example above, it should only work for the first assignment to the given key. I guess a workaround to this might be assigning those key-value pairs to a different table that doesn’t have any metamethods, but I’m not too sure.

I like @5uph’s solution here of implementing a mutator to modify the table’s contents, and that gives you the flexibility to do things with those changes.

2 Likes