Hello I just wanted to know in oop why do some people do
module.__index = module
e.g.
local module = {}
module.__index = module
like what does it mean to do module.__index = module and why do people do it and how does it help?
Hello I just wanted to know in oop why do some people do
module.__index = module
e.g.
local module = {}
module.__index = module
like what does it mean to do module.__index = module and why do people do it and how does it help?
It’s so that when you index for a nil value it falls back to the module
table where all the methods are
Can you give me an example of that?
local t = setmetatable({hello = nil},{
__index = function()
print("index fired.")
end;
})
print(t.hello) -- fires
Ok so I deleted my last post cause it was really confusing lol.
Alright:
local module = {LOL = 'hhaha"}
module.__index = module
Let’s define something thing’s here so I don’t make you confused
Module = the table called module above
CoolTable = A table which has it’s metatable attached to the table module using setmetatable
CoolTable also has some indexes, and values in it. CoolTable = {Hello = 'no'}
Based on the things I showed above it makes it so when CoolTable is indexed and the value of the index is nil, it fires .__index in Module. For example if we do CoolTable.LOL, CoolTable.LOL is nil so it fires.__index in Module. Now lua checks if the .__index is attached to a table. In this case yes, Module is attached to itself Module. Now lua returns the value of the index in Module.
In this case since Module.LOL is ‘hhaha’ it returns that.
so when we do print(Module.LOL) it print’s hhaha
Also keep in mind .__index can be attached to a function to, however I won’t be explaining that since your post asks about it attaching it to a table.
let’s explain some practical use cases of this. For example, two modules need the same set of functions and some additional functions. So why don’t we just make one module which contains these functions that these two modules will use so we don’t have to redefine the common functions in each module and waste memory?
local MasterModule = {}
MasterModule.__index = MasterModule
MasterModule.Echo = function(...)
print(...)
end
-----------------------------------------
local Module1 = {}
setmetatable(Module1, MasterModule)
Module1.Kill = function(Player)
if Player.Character then
Player.Character.Humanoid.Health = 0
end
end
-----------------------------
local Module2 ={}
setmetatable(Module2, MasterModule)
Module2.Kick = function(Player, Reason)
Player:Kick(Reason)
end
Module1.Echo("WOW I HAVE THE FUNCTION AND I DIDNT EVEN DEFINE IT IN MY MODULE XD")
Module2.Echo("OMG ME TO LOL ")
Both of them received Echo but all they had to do was set their metatable to the MasterTable. Instead of defining the Echo function in each module, we just make defined it in one table.
I see OOP examples, all you need is a diagram, so here you go, thrown together in about 5 minutes in paint because im bored
also didn’t include the fact that __index’s can be chained, but I felt that was out of the scope of this post, so quickly gonna bodge this for you
a = {c = 3}
b = setmetatable({b = 2}, {__index = a})
c = setmetatable({a = 1}, {__index = b})
print(c.a) --> 1 reading from itself
print(c.b) --> 2 reading from the __index table (which is b)
print(c.c) --> 3 reading from the __index table's __index (which is a)
__index is by far one of the most powerful metamethods out there, and it’s very useful in sandboxing. Roblox’s default ENV (holder of global variables) is actually a table with a locked metatable (out of this scope), that has an __index to the real ENV.
this explanation was by far the most helpful of all the examples I’ve seen
thanks!