Trying to figure out how __index works with tables
I saw them set the table of the class to __index like this
Car.__index = Car
and I don’t know why this is done, I know it means that you can access methods inside the class while in an object of the class, but I don’t know how it works I thought __index was an event not a property.
Well __index is technically neither of them. __index is a metamethod that fires when you try to index a key with no value attached to it but you don’t necessarily have to attach a function to it. You can attach a table to the __index metamethod and it will return the value in the table __index metamethod referencing to that is attached to that said key or it will do that whole metatable cycle again if there is no value attached to the key.
Here is a picture I made a while ago to visualize it better.
Basically, the __index pointing to itself doesn’t matter at all. In fact, you can do the very same without using it.
local object = {}
local meta = {__index = {}}
local __index = meta.__index
object.new = function()
return setmetatable({}, meta)
end
__index.mymethod = function() print'hi' end
Is the equipvalent of: semantic wise anyways
local object = {}
local meta = {}
meta.__index = meta
object.new = function()
return setmetatable({}, meta)
end
meta.mymethod = function() print'hi' end
This sounds more like a table confusion thing.
In lua, you can have table that have a key which points to itself.
local t ={}
t[t] = t --// ???????
print(t[t][t] == t) --> true
print(next(t) == t) --> true
-- module script
local module = {}
module.__index = module
-- basically, if I try to get a value that doesn't exist in a table, it will check if the table has a meta table and if it does
-- it'll search if the metatable has an "__index" property, and from there, whatever it's set to, it'll search through that to find the requested index
function module.new()
local new = setmetatable({}, module)
-- this creates a new table with it's metatable set to the ModuleScript's table
-- so now when I call something like "printf", It will search for it in the "module" table since I didn't define it here
new.__type = "class"
-- "__type" is not an actual metamethod, I just like to name properties like this
return new
end
function module:printf()
print(self.__type) -- this will either print "class" or "nil" depending on how it's called
end
return module
-- another script
local module = require(ModuleScript)
print(module:printf()) --> this would print "nil" because I haven't created the class yet
local myClass = module.new()
print(myClass:printf()) --> this would print "class" because I created the class and the module is able to find the "__type" property from it