All you need to know about Metatables and Metamethods

why does only __index fire?

local t = {
	t2 = {
		A = 100
	}
}

local clone = {}

setmetatable(clone, {
	__index = function(self, k)
		return t[k]
	end,
	__newindex = function(self, k, v)
		t[k] = v
	end,
})

while wait(1) do
	clone.t2.A += 100
end

The compound operator is really just the equivalent of

t.key = t.key + x

so it should fire both __index and __newindex.

The problem is in the code you wrote, the __index is fired when you index clone.t2. The A exists in t2 which is given by clone.t2, the key exists, there is not metatable in the first place, the += operation doesn’t fire any __index nor __newindex.

As you can see, this fires both

local t = setmetatable({}, 
{__index = function() print("hi") return 10 end, -- I return something so the operation doesn't error, as t.A += y is the same as t.A += t.A + y, the indexing of t.A happens, which would return nil, nil + 5 is not good
__newindex = function() print("bye") end})

 t.A += 5

But is there anyway I can fix it? I tried doing it like what you did so both fired but idk how to fix the code I showed above.

I just learned the metas true power, and it’s incredible

2 Likes

The A key shouldn’t exist and you should hook up a metatable for t2.

local t = {
	t2 = setmetatable({}, {
	__index = function(self, k)
		return 100
	end,
	__newindex = function(self, k, v)
		rawset(self, k, v)
	end,})
}

local clone = {}

setmetatable(clone, {
	__index = function(self, k)
		return t[k]
	end,
	__newindex = function(self, k, v)
		t[k] = v
	end,
})

while wait(1) do
	clone.t2.A += 100
end
```

I actually got a way to fix it and now I’m using it in this function.

function module:GetFakeProfile(profile)
	local profileId = tostring(profile)
	if fakeProfiles[profileId] then return fakeProfiles[profileId] end
	
	local fakeProfile = {}
	fakeProfile.Data = {}
	fakeProfile.ID = profileId
	fakeProfile.DataChanged = Signal.new()
	
	function fakeProfile:GetRealProfile()
		return profile
	end
	
	if not getmetatable(fakeProfile) then
		setmetatable(fakeProfile, {
			__index = function(self, k)
				return profile[k]
			end,
			__newindex = function(self, k, v)
				profile[k] = v
			end,
		})

		setmetatable(fakeProfile.Data, {
			__index = function(self, k)
				return profile.Data[k]
			end,
			__newindex = function(self, k, v)
				profile.Data[k] = v
				fakeProfile.DataChanged:Fire(k, v)
			end,
		})
	end

	fakeProfiles[profileId] = fakeProfile
	return fakeProfile
end
2 Likes

my brain cannot handle this, this is the only last i need to learn on lua basics

1 Like

update: Learnt em! it basically table with index events lol.

1 Like

rrebimetef

  1. List item

either

not just that

it can also has Add, __Mode and more! this helps me though