Similarly to Value.Changed(), I’ve been wondering if there’s something for Tables? I did try setting a metatable, however the function won’t run if something has been inserted or removed.
You can check every frame or you can use metatables.
EDIT: I made this a while ago but this is a way to do it with metatables.
local Class = {}
function Class:__index(key)
return rawget(self, "proxy")[key]
end
function Class:__newindex(key, value)
local proxy = rawget(self, "proxy")
proxy[key] = value
if key == "Property" then
print("Property was changed to: "..value)
end
end
function Class.new()
local self = setmetatable({}, Class)
local proxy = {}
function proxy:Method()
print("Hello world!")
end
rawset(self, "proxy", proxy)
return self
end
local obj = Class.new()
obj.Property = 20
obj:Method()
Metatables don’t get fired by table.insert
and table.remove
.
You have to add values manually.
function table.insert(t, v)
t[#t+1] = v
end
function table.remove(t, k)
t[k]=nil; --> Indexes don't get shifted, have that in mind.
end
local t = {}
setmetatable(t, {
__newindex = function(self, k, v)
if v then
print('new value', k)
else
print('value removed', k)
end
end
})
While I think @Legoracer solution works, it’s lacking in the sense that it’s overriding the default table insert and removing behavior, which is generally not desired as you lose the ability to insert or remove at any position. A better way is to have the overridden function callback the original function and check for any event handler in the table and if present call it. Metatables are fancy, but are not always the solution.
local insert = table.insert
local remove = table.remove
function table.remove(...)
local params = {...}
local t = params[1]
if t["OnRemove"] then
if t.OnRemove(...) then
remove(...)
end
end
end
function table.insert(...)
local params = {...}
local t = params[1]
if t["OnInsert"] then
if t.OnInsert(...) then
insert(...)
end
end
end
t = {
1, 2, 3, 4, 5, 6, 7,
OnRemove = function(self, pos)
print(self, pos)
return true
end,
OnInsert = function(self, vp, value)
print(self, vp, value)
return true
end
}
table.remove(t, 2)
print(table.concat(t, ", "))
table.remove(t, 3)
print(table.concat(t, ", "))
table.insert(t, "end")
print(table.concat(t, ", "))
table.insert(t, 1, "start")
print(table.concat(t, ", "))
With this implementation you must return true to allow the inserting or removing in the event handler, you can return false to block the insertion or removal, say you only want numbers to be added.
Hey, @Destrings. I see what you mean, I’ve bumped into another problem which prevents me from modifying a table. " [ Attempt to modify a readonly table] " Not sure what’s the issue here
Right, in ROBLOX, due to security reasons, you can’t modify the “table” table. So you can’t override the functions. You will have to rename them as so
function remove(...)
local params = {...}
local t = params[1]
if t["OnRemove"] then
if t.OnRemove(...) then
table.remove(...)
end
end
end
function insert(...)
local params = {...}
local t = params[1]
if t["OnInsert"] then
if t.OnInsert(...) then
table.insert(...)
end
end
end
t = {
1, 2, 3, 4, 5, 6, 7,
OnRemove = function(self, pos)
print(self, pos)
return true
end,
OnInsert = function(self, vp, value)
print(self, vp, value)
return true
end
}
remove(t, 2)
print(table.concat(t, ", "))
remove(t, 3)
print(table.concat(t, ", "))
insert(t, "end")
print(table.concat(t, ", "))
insert(t, 1, "start")
print(table.concat(t, ", "))
You could use setfenv() on any functions that need to do any inserting or removing, but please nobody ever do that - it would most definitely be bad practice!
(or if you’re really hardcore and/or love terrible ideas, sandbox everything in your game)