New to Metatables

Usually when I see scripts based on object orient programming I see “table.__index = table” in the beginning of a script. Can someone tell me a simple definition on why it is used or useful. Thanks!

If you search online there are a lot of explanations though it can really technical on it but I’ll give my own explanation on how I understood it.

Delete this line.

Once you do you will find out you cannot access the functions of the module script like

--line will error because the .__index line was deleted
local Porsche = Car.new()

Therefore that line is so the metatables can do it’s lua syntax magic to access this function.

Edit: this explanation doesn’t fully cover why it’s useful though, I’ll link some other posts if I find em.

__index is a metamethod that makes the script search in the connected table for a value that doesn’t exist in the main table.

example

local myTable = {x=10}
myTable.__index = myTable

local meta = setmetatable({}, myTable)
print(meta.x) --> prints 10 because the main table '{}' doesn't have that index but the metatable has that index

You could also connect it to a function.

example

local myTable = {}
myTable.__index = function(self, index)
   -- this metamethod fires when a nil value is indexed in the main table

   return 0
end

local meta = setmetatable({}, myTable)
print(meta.x) --> prints 0 because that's what the function returned
1 Like

I know what __index does but why do you need to set it equal to the table you are indexing? Can’t you just set it equal to a function

1 Like

The reason why is because the table itself is going to become a metatable. And the script will look for the __index key in the metatable if it exists. Once it does that, it will look inside whatever table is connected to it. It’s mainly used for OOP or Object Oriented Programming. You can equal it to a function but that’s only if it’s needed

So when you are doing Table.__index = Table you are making Table a metatable?

If you intend to. If not, then it’s unneeded

Using @HugeCoolboy2007 .x example

This:

local myTable = {x=10}
myTable.__index = myTable

local meta = setmetatable({}, myTable)
print(meta.x) --> prints 10 because the main table '{}' doesn't have that index but the metatable has that index

Is equal to this:

local myTable = {x=10}
myTable.__index = function(someTable,index) 
	return myTable[index]
end

local meta = setmetatable({}, myTable)
print(meta.x) --> prints 10 because the main table '{}' doesn't have that index but the metatable has that index

Short hand notation to index the metatable “table” instead of the table we want to modify, the table we are modifying in this case is stored in a variable called meta and is the empty table {} in the first parameter of setmetatable({}, myTable) which is being returned.

–Documentation on the .__index function for the 2 different scenarios
table refers to the table that is being modified, the first parameter of setmetatable.

Fires when table[index] is indexed, if table[index] is nil. Can also be set to a table, in which case that table will be indexed

4 Likes

Just to get it straight if I do “Table.__index = Table” and if I index it for an example

local NewTable = {}
Table.__index = NewTable
print(Table.x)

It will check if x is in the NewTable and if it isn’t it will return nil?

1 Like

Try checking using a compiler by running the code in studio, the compiler will give you a straight answer whether it’ll work or not.

For the example post I gave with the two equivalents code, I ran the code in a script in studio to make sure it works and to reconfirm my understanding.

Currently, all I can say with your code as is:

It’s going to error because Table is not defined.