Fully Detecting Table Changes

For a cool side-project I have made what I call a “kyletable”. It is still in VERY early development but it allows you to detect every change in a table via the __changed method.
Feedback would be very appreciated!

Edit: a “kyletable” is a modified metatable with a unusable __newindex method.

Source

function setkyletable(root, binds)
	local function merge(to, from)
		local merged = {}
		
		for i,v in to do
			merged[i] = v
		end
		for i,v in from do
			merged[i] = v
		end
		
		return merged
	end
	
	local function bind(virtual)
		return setmetatable(virtual, merge(binds, {
			__newindex = function(self, index, value)
				if rawget(self, index) == value then
					return
				end

				if rawget(binds, "__changed") then
					rawset(virtual, index, value)
					task.spawn(function()
						rawget(binds, "__changed")(self, index, value)
						
						if typeof(self) == "table" then
							for i, v in self do
								if typeof(v) == "table" then
									bind(v)
								end
							end
						end
					end)
				end
			end
		}))
	end

	return bind(root)
end

Usage Examples

local hooked = setkyletable({}, {
	--// self is the root/sub table changed
	__changed = function(self, index, value)
		print(self, index, value)		
	end
})

hooked.Hi = "Hello..."
hooked.Test = {}
hooked.Test.Test = "Hello!"
local data = {}
data.Points = 20

local hooked = setkyletable(data, {
	--// self is the root/sub table changed
	__changed = function(self, index, value)
		print(self, index, value)
	end
})

hooked.Points += 200
10 Likes

epic, i have nothing else other than to say you did a good job

1 Like

Unless I have done something wrong, so far it only works for NEW keys, and not existing ones. The second example you gave does not actually work. If I try to update an existing value __changed is not run.

It should work, can I see your script?
I found the problem and will be pushing a fix for it soon!

1 Like

What’s the point of doing this when there are default metamethods to detect these changes?

Metatables cannot detect subdirectory changes by default. That is why I created “kyletables”

1 Like

Yeah because __newindex only if thr key on the table was not set, once it’s set it will not call __newindex

Solution is proxies

Yeah, I’m still working on a proper fix. The reason I don’t want to use proxies is it doesn’t return the table (unless there is a metatable fix I haven’t discovered yet) :slight_smile: