I need to detect this change, .__index and .__newindex don’t work for this case.
I need to detect it because if a property of an object was changed for example its attack it needs to change in real time. Just like if you change a position of the part it moves
You are going to need to either fire a function whever it’s changed or everyframe, check if it’s changed by doing something like this
E = mytable.cool
while wait() do
if mytable.cool~=E then
change
end
end
Though metatables work for this, I believe a better or more ‘proper’ solution is to send a signal whenever the table is changed. Theoretically, unless you are writing this for somebody else or using third-party scripts in conjunction, you will always have control over what happens with the table. As such, you should also be able to fire a separate function whenever you modify the table in your own scripts. Just food for thought though, as metatables aren’t the worst idea here.
You have full control over your own scripts.
Whenever you write this
exampleTable.key=10
write this instead
print("Changed key in exampleTable!")
exampleTable.key=10
or for the sake of example
newValue = 10
if exampleTable.key ~= newValue then
print("key was " .. exampleTable.key .. " and has been changed to " .. newValue)
exampleTable.key = newValue
end
Oh, yah I was thinking that but I wondered if there was a more idk how to describe it like better? I was using OOP to make a class. I know I could call an update function int he script after changing the property, but I was just seeing if their was a better way
Metatables are great. I love them. They can be messy if you don’t do it right, and I can’t quote any sources here but I remember a lot of remarks about performance or impracticality on the old forum.
They are basically required for OOP. If you are working with OOP, then you need to learn all you can about metatables, it’s pretty simple.
As a basic rundown, you get either a table or a blank userdata (created by newproxy, basically does nothing) and assign a table of functions to it using getmetatable and setmetatable.
If you are going the OOP route, I recommend using newproxy, that looks like this.
local testClass = {}
testClass.New = function(self, Value)
Value = Value or 5 -- if no Value is given, default to 5.
local object = newproxy(true) -- don't even ask what this does, you can look it up but it doesn't make much difference.
-- it just gives a base userdata to modify, and it only accepts 'true' as the argument on Roblox.
-- you can use a table instead of newproxy, but it has a couple of limitations when using metatables.
local mt = getmetatable(object)
mt.__index = function(key) if key=="Value" then return Value else return self[key] end)
-- this function returns the current Value if you ask for object.Value, otherwise it returns whatever it can find in testClass table.
-- this is useful because the testClass table would ideally be filled with functions and methods and default properties for this class.
mt.__add(self, other) -- when this object is added to another
self.Value = self.Value + other.Value -- I have no safety conditions here, so this will error if the second argument has no 'Value' property.
return self
end
return object
end
testClass.Double = function(self) -- a small function just to demonstrate how to populate the testClass table
self.Value = self.Value*2
return self
end
local testObject1 = testClass:New(8) -- create a new testClass object with a Value of 8
local testObject2 = testClass:New() -- create a new testClass with a default Value
print(testObject1) --> userdata blah blah
print(testObject1.Value) --> 8
testObject1 = testObject1 + testObject2 -- Impressive that you can give your classes their own operation functions, yeah?
print(testObject1.Value) --> 12
print(testObject2.Value) --> 5 -- This value was not changed, but we can modify that in the function if we want.
print(testObject1:Double()) --> 24
testClass.__newindex = function(_table, index, value)
-- Content
end
does this method only fire when table[index] tries to be set (table[index] = value), only IF table[index] is nil? Or every time when a table[index], even if it’s value is nil or not, changes
Yes that’s correct, it only fires when a non nil index is set to a value you can try it out in studio. Which is why you need a middle man table to detect it