Hello! Today I want to share everyone on how to do OOP without the indexing method.
Like this:
local module = {}
function module.new()
local base = setmetatable({}, {__index = module})
function base.methoda()
return base
end
function base:methodb()
print("hi")
end
base.value = 0
return base
end
return module
That’s all I want to share. And this also prevents the class’s methods to flood over the module.
Why do this? It will only burden the memory and create new tables each time! __index will be much better because it doesn’t create new tables but simply references the root.
My question is why do this. Setmetatable __index is the most memory efficient way to go about OOP, if each time you create an instance you create a new table and assign functions to it it just overloads memory for no reason
not exacly, Composition is great alternative, and can be used instead of inheritance via mtametamethood, but for private methoods, not shared it’s best methood
Composition like this have no memory advantage or disadvantage over metamethoods:
Class.Methood = Methoods.Methood
is the same as
Class.__index = Class
function Class:Methood()
end
Remember, that semicolon must be used in original table
Tables and functions in lua are passed via reference, not a copy, this is why they can cause memory leaks, because they are only referenced
Now some comparison:
Composition
Use when you need to use methood in many classes
Use when you need to use only one methood from another class
Don’t use it for private methoods
Remember to add semicolon in original table
Inheritance via __index
Use when dealing with private methoods
Use to simulate inheritance
Use when you need all or most methoods from another class
Yeah thats what I want to say! Thanks for pointing out, but for composition you can still simulate inheritance by:
Assuming we have module a, b in Replicated storage. We have:
local module = {}
setmetatable(module, {__index = module})
function module.new()
local base = {}
setmetatable(base, {__index = base})
function base.methoda()
return base
end
function base:methodb()
print("hi")
end
base.value = 0
return base
end
return module
b:
local module2 = {}
local originalmodule = require(game.ReplicatedStorage.a)
setmetatable(module2, {__index = module2})
function module.new()
local base = {}
setmetatable(base, {originalmodule, __index = base})
function base.youcanonlygetthis()
return base
end
base.value2 = 0
return base
end
return module2
And for private method, just make an function that doesnt belong to the object that will return, thats all.
In these scenarios what’s stopping you from defining the method function in a separate module and then using them in both individual classes and still being able to use inheritance?