What about the static method for metatable?
Static and member methods alike will be “inherited” using the setmetatable method.
I really want to do OOP, but I reject using metatables. Is this possible?
Yes, its possible. Example:
local module = {}
function module.func(self, a)
print(self.num + a)
end
function module.new()
return {
num = 0,
}
end
-- OR
local module2 = {}
function module2.new()
return {
num = 0,
func = function(self, a)
print(self.num + a)
end,
}
end
local mod = module.new()
mod.num = 1
module.func(mod, 2)
local mod2 = module2.new()
mod2.num = 1
mod2:func(2)
-- both print three
I just recommend using metatables as you dont need to understand them to do OOP, and you dont need to either define functions weirdly (the second one) or call them weirdly (the first one).
This is a very good tutorial, thanks!
Oh well, how do you inherit base class Car
and have your own functions
local redCar = RedCar.new()
redCar:Drive() -- Inherited from base method in Car
redCar:Honk() -- The custom method in redCar
The distinction(s) between OOP and ‘module-based’ scripting is that OOP uses the .new constructor function (and meta-tables). All OOP are made in module scripts, but not all module scripts are necessarily OOP-based.
What I mean is - say, you create your gun with just the module, and you have functions inside that module that allow you to control the behavior of your new gun, and your fields (the gun’s damage, range, ammo etc.) are stored probably inside a dictionary. This means you have to individually pass on each argument for each function, or you could just pass on the table as an argument. (you will have to define it accordingly)
OOP is more efficient, because once you enter the fields in the .new function and store the object inside a new variable, you don’t have to enter them again. When you wanna call a function for the gun, you can use the colon notation, and it will get access to the table in the form of ‘self’.
Additionally, the approach with meta-tables also saves more memory, as it doesn’t duplicate the same functions to store in each object. The only thing that that constructor returns is a table containing the fields and its meta-table set to the Gun module. Consequently, whenever you try to call a function from the object (your table), instead of returning nil, the _index meta-method comes into play and looks for the function in the meta table, which is set to the module. So, each object only contains the fields, and the functions controlling their behavior are stored only once in memory.
Hope this answers your question!
Nice tutorial, you helped me so much !!!
Guys you might not believe this but I naturally invented this method to use for my games without even learning tutorials I just discovered this was a thing. Great tutorial I never even thought of changing self and the modules index and using metatables that way!
The way you explained it clicked in a way that other tutorials couldn’t for me! Thank you!
I kinda understood now the whole reason of __index & setmetatable. Thank you so much for this!