How can I detect changes in Player Data Storage and OOP?

I’m trying to create a Player Data Storage modulescript using object oriented programming. I realized that I need to detect when a player data object changes data. I found a way to detect changes in table, here:

The thing is, I am really, really confused as to how I can implement this. This is my first attempt at OOP, after all. But I semi-understand metatables.

My current code can find when a new index is created, but it can’t find when an index changes. Here’s my code right now, fyi:

local playerData = {}

local defaultData = {
	Name = nil,
	UserId = nil
}
local objects = {}

local bindableEvent = Instance.new("BindableEvent")
playerData.Changed = bindableEvent.Event

playerData.__index = playerData

-- The __newindex metamethod is called whenever a new index is assigned to the table
function playerData:__newindex(index, value)
	
	print("NEW INDEX CREATED")
	
	print(index, value, objects)
	-- Get the raw value currently stored in the table
	local oldValue = rawget(self, index)

	-- Only fire the changed event if the value is actually different
	if oldValue ~= value then
		-- Store the new value using rawset to avoid recursive calls to __newindex
		rawset(self, index, value)

		-- Fire the changed event with information about what changed
		bindableEvent:Fire(
			self.UserId,
			index,
			oldValue,
			value
		)
	end
end

function playerData.new (player: Player) -- Constructor
	
	local specificDefaultData = table.clone(defaultData)
	specificDefaultData.Name = player.Name
	specificDefaultData.UserId = player.UserId
	
	local self = setmetatable(specificDefaultData, playerData) 
	
	--[[
	When a function is indexed, it won't be found in the new playerData instance. 
	Thus, it will look in playerData class to find all the functions! 
	]]--
	
	objects[self.UserId] = self
	
	return self
	
end

function playerData.findPlayerData (player: Player, createIfNotFound: boolean)
	
	local userId = player.UserId
	
	if objects[userId] then
		return objects[userId]
	else
		if createIfNotFound then
			
			local playerFromId = game.Players:GetPlayerByUserId(userId)
			
			if playerFromId then
				playerData.new()
			end
		end
	end
	return nil
end

function playerData:Destroy()
	if self.UserId then
		objects[self.UserId] = nil
	end

	-- Clear the object's data
	for k, _ in pairs(self) do
		self[k] = nil
	end

	setmetatable(self, nil)
	
	self = nil
end

return playerData

Thanks for reading!