Metatables screwing with my head

Hi there!
I was doing some experimenting with metatables. And I still havent fully grasped what this code does
classtable.__index = classtable

So, this is the code i wrote while experimenting:

local metatable = {__index = function(t,i)
	print(t,i)
end,}
local classtable = {}
setmetatable(classtable, metatable)
classtable.__index = classtable
function classtable.new()
	local self = {one = 1}
	setmetatable(self, classtable)
	return self
end

local Instance = classtable.new()
print(Instance.one) 
print(Instance.two) 

output: image

Now, the thing is that if I comment out classtable.__index = classtable
the __index metamethod doesnt run. Now this screwed with my mind. Shouldnt it be the other way around?

1 Like

There’s 2 layers of meta tables here.

Instance → classtable → metatable
The arrows represent the __index function when you try to index something that doesn’t exist. In this case it is when .two is indexed (you can try commenting it out).

When you index instance you will index class table (classtable.__index = classtable)

When you index classtable it will execute the __index metatable function printing (t,i)

If you remove (classtable.__index = classtable) it will break the link and the table and index will not be printed out:

Instance -\ → classtable → metatable

2 Likes

Maybe this video might help you understand metatables some more

2 Likes

Ok, now I get it! I was mixing up metatable.__index and classtable.__index thinking they were basically the same.

Just to make sure, heres how I understand whats happening:

  • I index Instance with .two which is nil, so no index exists.

  • Then Instance checks its metatable which is classtable for an __index-method and because that __index-method is set to classtable by this line:
    classtable.__index = classtable it checks classtable for the .two index.

  • Then the cycle repeats. classtable has no .two index so it checks its metatable which is metatable for an __index-method and finds it and runs it.

So when I comment out classtable.__index = classtable, classtable basically stops being a metatable. So Instances metatable, which is classtable, then has no __index-method.