__index metamethod
I think you kind of have the whole concept backwards between the table and the metatable. __index is invoked when a value that doesn't exist in the regular table, is indexed. So making __index point to the regular table when it's only invoked because it's not in the regular table, won't get you very far.
I think what you're trying to do, is make a regular table inherit some methods and properties the __index metamethod provides. First, you should define a table that will hold these methods and properties. Next, we'll assign a function to __index that will control what gets returned, and how.
Before we get into that, it's important to know how self works. self is a hidden variable that always holds a reference to the table the function is in, only if the function is indeed written as a method (i.e, using : instead of the standard . format). Acknowledging how this variable works is vital for understanding how to create custom methods.
So with all that out of the way, we can make a table that will hold the functions that our normal table will perceive as methods. We'll just call it methods, and we'll call our normal table tab.
local tab = {}
local methods = {}
This is where self comes in. Since __index will return functions from the methods table, we need to keep the returned function a method. We do this by returning a different function, that returns the called function from the table. It seems a bit confusing now, but looking at the code should clear things up a bit. So now let's set the metatable to tab.
local tab = {}
local methods = {}
setmetatable(tab,{
__index = function(t,k)
local v = methods[k]
if type(v) == "function" then
return function(_, ...)
return v(t,...)
end
end
end
})
Now we've created a way in which __index will return a non-method formatted function, as a method. Keep in mind, this will mean every function you store in methods will have it's first parameter defined as the table.
Final product
The final product should look something like this:
local tab = {}
local methods = {
printName = function(self)
print(self.Name)
end
}
setmetatable(tab,{
__index = function(t,k)
local v = methods[k]
if type(v) == "function" then
return function(_, ...)
return v(t,...)
end
else
return v
end
end
})
tab.Name = "Hello"
tab:printName()
Questions?
This is a lot to take in if you're new to metatables. If you have any questions, I have a pretty good answer on how methods work here: https://scriptinghelpers.org/questions/28060/gamedestroy-a-thing
If you're still confused about anything, just let me know.
2 comments
Try inserting 'Name = "Table1"' into the funcs table.
I have already tried something similar. I put 'ayy lmao' into the funcs table, and it just printed 'ayy lmao', even when I changed the name value after setting the metatable.