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
iâve mostly used __index for inheritance.
local Class = {}
Class.__index = Class
function Class.new(name)
local object = {}
object.Name = name
setmetatable(object, Class)
return object
end
function Class:GetName()
return self.Name
end
return Class
now you can do this and the object created will have access to the modules :GetName function
local class = require(script.Parent)
local object = class.new("Dog")
print(object:GetName()) --> prints "Dog"
print(class:GetName()) --> prints "nil"
this happens because the object didnât have the function called :GetName() so it fellback on its index. (which is shared with the âClassâ table/module) and found the function there instead.
so this is beneficial because you can share functions/properties instead of giving each object/table its own set.
someone correct me if im wrong though
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.