I understand the .__index metamethod written like so:
local myTable = {10, 15, 20}
local myMetaTable = {
__index = function(table, index)
print("No data at this index!")
return 1
end
}
setmetatable(myTable, myMetaTable)
local myNumber = myTable[4]
local addNumber = myNumber + 5
print(myNumber, addNumber)
But I am confused when its written like this:
local car = {}
car.__index = car
return car
What does this do? And is this different compared to my first coding example above, if so how?
When using a function as __index, you can manually retrieve the value. Specifying a table is a “secondary” thing to check, which is better used for referencing methods (which are usually unchanged).
By itself, that does nothing other than create a property named __index on the table tycoon set to itself.
That usage however is useful when implementing inheritance/OOP and using the base table as the metatable. So building out that tycoon.new() method it becomes relevant
function tycoon.new(type: string)
local self = {
TypeOfTycoon = type
}
setmetatable(self, tycoon)
return self
end
-- in other code...
local BurgerTycoon = tycoon.new("Burger")
local TacoTycoon = tycoon.new("Taco")
Now if you reference a property or method which does not exist on BurgerTycoon or TacoTycoon, the __index metamethod kicks in and it will failover to checking the base class, tycoon. Setting an __index metamethod to a table is simply a shortcut for a function that returns the corresponding key from the table, just like your function above.
You can learn more on the official Roblox style guide here: Roblox Lua Style guide, this is referred to as the “One True Pattern”.