Setmetatable ignore updating table when using loop although it supposed to

I want to update my table. But I wouldn’t update even if I update the Table then setmetatable it or after it still only result with it not updating.
It work by setting the value normally but when I try to use for loop on it to counts how many instance are in the child it just won’t work.

local SharedFolder = ReplicatedStorage:WaitForChild("Shared")
local ServerFolder = ServerScriptService:WaitForChild("Server")
local ClientFolder = game.StarterPlayer.StarterPlayerScripts:WaitForChild("Client")

local Classes,Packages,Engine,Modules,Services,Assets,Remotes = {},{},{},{},{},{},{}
local MetaData = {["Modules"]=0,["Running_Modules"]=0,["Loaded_Modules"]={},["Error_Modules"]={}}

local Settings = {["Debug"]=true}
local Framework={
	["Shared"]={
		["Folder"] = SharedFolder,
		["Classes"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Table"]=Classes,
				["Folder"]={}
			}},
		["Packages"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Table"]=Packages,
				["Folder"] = {}
			}},
		["Engine"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Table"]=Engine,
				["Folder"] = {}
			}},
		["Modules"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Table"]=Modules,
				["Folder"] = {}
			}},
		["Services"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Table"]=Services,
				["Folder"] = {}
			}},
		["Assets"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=false,
				["Table"]=Assets,
				["Folder"] = {}
			}},
		["Remotes"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=false,
				["Table"]=Remotes,
				["Folder"] = {}
			}},
	},
	["Server"]={
		["Folder"] = ServerFolder,
		["Scripts"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Folder"] = {}
			}},
		["Classes"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Folder"] = {}
			}},
		["Modules"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Folder"] = {}
			}}
	},
	["Client"]={
		["Folder"] = ClientFolder,
		["Scripts"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Folder"] = {}
			}},
		["Classes"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Folder"] = {}
			}},
		["Modules"]={
			["Data"] = {},
			["Setting"]={
				["Meta"]=true,
				["Folder"] = {}
			}},
	},
}

for _,Folders in pairs(Framework) do
	local Folder = Folders.Folder
	for Name:string,Services in pairs(Folders) do
		if typeof(Services) == "table" then
			Services["Setting"]["Folder"] = Folder[Name]

			if Services["Setting"]["Table"] and Services["Setting"]["Meta"] then
				if Settings["Debug"] then
					Services["Data"] = MetaData
					Services["Data"]["Modules"] = #Services["Setting"]["Folder"]:GetChildren() --Supposed to change
				else
					Services["Data"] = nil
				end


				setmetatable(Services["Setting"]["Table"],{
					__index = Services, --Have indexed but won't change

					__call = function(Table,Object)
						print(Table["Data"]) --Modules haven't change
					end
				})
			end
		end
	end
end

Modules()
--All I think that it must be something when using #Services["Setting"]["Folder"]:GetChildren()

Is your MetaData table supposed to be unique for each service or is it supposed to be shared?

The services variable are shared, the for loop is just to set it up and setmetatable for it include function and index to the actual services in the framework table.

Oh, okay I think I see what you’re saying, for loops don’t run what’s in a metatable even if you set the index to another table.

There are two ways that I can think about that allow you to sort through the index with a for loop:

------------------ [ 1 ] ------------------
-- // From your provided info
local Table = setmetatable(Services["Setting"]["Table"],{
		__index = Services, 

		__call = function(Table,Object)
			print(Table["Data"]) --Modules haven't change
		end
})

local Services = getmetatable(Table).__index -- // Probably not recommended; 

for index, value in pairs(Services) do 
    -- . . .
end

------------------ [ 2 ] ------------------

local Methods   = {}
Methods.__index = Methods,
Methods.__serviceIndex = Services,
Methods.__call  = function(Table,Object)
		print(Table["Data"]) --Modules haven't change
end
-- // returning meta index
function Methods:GetService()
    return self.__serviceIndex
end

local Table = setmetatable(Services["Setting"]["Table"], Methods)

for index, value in pairs(Table:GetService()) do
    -- . . .
end

Don’t mean to keep editing this just small errors but does relatively the same thing.

2 Likes

I have been trying your methods but I can’t seem to how to fix my problems. I don’t understand what wrong with my code or why it act like that maybe I will try to find a workaround

I just know my problem and has fixed it. It turn out that this line of code

Services["Data"] = MetaData

has caused the problem instead of

#Services["Setting"]["Folder"]:GetChildren()

It seem like the problem was because I am setting the Table Variable into Another Table Variable which caused it to like clone each other. It was an easy fix by cloning the table.