I was wondering if there is a metamethod or some other thing that will allow me to see if a new value was added to a table?
--[[Purpose:I'm making a script that is finding npcs with the value "Shop" and making them into a shop]]-- NPCs={}--Table where the npc's will be stored function FindNpc()--Will Search Workspace for a humanoid if it finds it then it search for the value "Shop" then insert the NPC to the Table for Index,Objects in pairs(game.Workspace:GetChildren()) do local FoundHumanoid = Objects:FindFirstChild("Humanoid") if FoundHumanoid then local FoundShopValue = FoundHumanoid:FindFirstChild("Value") if FoundShopValue then if FoundShopValue.Value == "Shop" then table.insert(NPCs,FoundHumanoid.Parent) end end end end end FindNpc() --To be Finished
Edited:
--[[Purpose:I'm making a script that is finding npcs with the value "Shop" and making them into a shop]]-- NPCs={}--Table where the npc's will be stored Metatable = { __newindex = function(self,index,value) print(value) end } setmetatable(NPCs,Metatable) function FindNpc()--Will Search Workspace for a humanoid if it finds it then it search for the value "Shop" then insert the NPC to the Table for Index,Objects in pairs(game.Workspace:GetChildren()) do local FoundHumanoid = Objects:FindFirstChild("Humanoid") if FoundHumanoid then local FoundShopValue = FoundHumanoid:FindFirstChild("Value") if FoundShopValue then if FoundShopValue.Value == "Shop" then table.insert(NPCs,FoundHumanoid.Parent) NPCs.x = "a"-- Y U NO print the value end end end end end FindNpc() --print(NPCs[1]) --To be Finished
If there is a way to see if a value was added to a table if so what is it?
The __newindex metamethod should do the trick. It triggers when a new index is added to a table without the use of the function rawset (this suggests that table.insert will not trigger __newindex).
Here's an example that prints out the index and the value when it is set...
local t = { } setmetatable(t, { __newindex = function(self, index, value) print(index, "=", value) end }) t.x = "a" --> x = "a" table.insert(t, "test") --> no output, uses table.insert t[2] = 2 --> 2 = 2
Sukinahito's answer is a good, direct answer to the question. (I believe Lua 5.3 even fixes the problem that table.insert
ignores metatables -- though since ROBLOX is on 5.1, that's a long, long ways away (you can also fix it yourself))
However, that is not the best approach to take to solve this problem.
There is a concept (that comes largely from Object Oriented Programming) called information hiding in computer science. This means separating the way you use something with the way that it works.
In this case, it would mean that when you're trying to make new NPCs (or remove them, get them, etc) you don't actually use the NPCs
table; you instead use a few functions (which are the only way to get to the NPCs
table)
This means you can do lots of extra stuff, like responding to a new element, without having a complicated API. It also means you won't confuse the user since there will be an explicitly approved way of getting objects, changing them, making new ones, etc.
This might look like this:
do local NPCs = {} -- This hides NPCs as a variable after the `end` for this `do` (since it's local) -- functions are global, so they can be used outside of the `do end` function isNPC( thing ) for _, obj in pairs(NPCs) do if obj == thing then return true end end return false end function newNPC( npc ) if not isNPC( npc) then table.insert(NPCs, npc) -- Now do whatever you want to do it: Instance.new("NumberValue", npc).Name = "Health" end end function removeNPC( npc ) assert( isNPC(npc) ) for i = #NPCs, 1, -1 do if NPCs[i] == npc then table.remove(NPCs, i) end end assert( not isNPC(npc) ) end function getNPCsNear(point, distance) local result = {} for _, npc in pairs(NPCs) do if (npc.Torso.Position - point).magnitude < distance then table.insert(result, npc) end end return result end end
The other nice result of this is that you provide explicit, clear ways that you're allowed to get information.
For instance, in the above, there is no (reasonable) way to get a list of all NPCs.
That's a good thing -- there's no good reason some random part of your script should be able to affect the entire world.
At the same time, you're provided with a neat little function to get everything nearby -- also eliminating the need for that code to ever appear twice in your code elsewhere.