Why do I see some people using __index like this?

Why do some people use __index like this?

local Table = {}
Table.__index = Table

-- Just for example
print(Table.hdsjfanfmwioajf)

I’m kind of new to metamethods and this really confuses me, I don’t understand why people do that, just running Table doesn’t do anything.

This is my general idea of what __index is meant to be used for:

Table.__index = print("No value found")

It defines the behaviour whenever table[index] is fired if the return value is nil. Basically, that line of code

Table.__index = print("No value found")

makes it so that if you try to call table[some index that doesnt exist], it prints out “No value found”

1 Like

__index gets the values of the table (if it’s a table value).
Just returning table does something.

local example0 = { test = "hello" };
local example1 = setmetatable({ }, { __index = example0 })
print(example1.test) --> hello
1 Like

Yeah I know that, but I don’t understand why some people use it like this:

Table.__index = Table

That wouldn’t do anything, would it?

Generally, people use it in OOP so they can create a new instance of the class with setmetatable. For example:

local Class = {Value = 5}
Class.__index = Class; --// Points to the Class itself and it's properties

function Class.new()
    return setmetatable({}, Class); --// Creates a new instance, will not affect the actual Class
end

function Class:GetValue()
    return self.Value --// self = Class
end

print(Class.new():GetValue()) --// 5, GetValue works since __index grabs it
2 Likes

Ok thanks I understand a bit more now, but what I don’t get is the point of making __index = itself.

That won’t work. That calls print("No value found") and sets Table.__index to the value that print returns, aka nil.


You can set __index to a table or a function. The function will be called with table, index if they index something that’s not actually part of the main table, and the __index table will be indexed with the index if it’s not a part of the main table.

4 Likes

True, not really thinking much about it. You need to set it as a function i.e function() print(“whatever u want”) end. Afaik there’s no reason to set the Table to itself there.

They’re probably using the Table itself as a metatable for a different table, like in the class example ReturnedTrue gave where the class is a metatable for each instance of that class.

3 Likes

I don’t really get why that wouldn’t work without the __index line. Wouldn’t GetValue search the empty table for Value, not find it, then search for metatables, then finding Class as a metatables realize that Value is a valid member of Class and print 5? I don’t get why that __index line does anything.

That is exactly why you use the __index metamethod.

Without __index, setting the Ckass as a metatable would do nothing - a metatable’s properties and methods aren’t shared as default.