I plan on learning how to use metatables
because I can see clear and obvious
reasons how metatables
can be very handy
and useful when coding.
I was wondering
where I should start
, I have done some research, found some pretty decent and lengthy articles that can help.
However, if anyone can recommend where I could start learning in order to get the hang of metatables it would be much appreciated.
I am also thinking I am not the only one trying to learn how metatables work in order to advance
their use of OOP, so I thought an answer to this question wouldn't just benefit me but everybody else with the same interest.
Any suggestions are appreciated. Thanks in advance!
You can read this or this but metatables is what you need to know. I can give you simple explanation of how they work. First you need to know setmetatable
function, it's a function that accepts 2 arguments, table
and.. table
where the first one is the one you want to set metatable to and the second one is the actual metatable. So you would do this
local MyTable = {} local MyMetatable = {} setmetatable(MyTable, MyMetatable) --/getmetatable does what it says, it returns metatable which given table --\is connected to, returns nil if none are getmetatable(MyTable) -- returns MyMetatable
Now you have a metatable, but it's useless, that's why you use metamethods
, the list of them is in the middle of this page, the most used metamethod is probably __index
, here is how it works:
local MyTable = {} local MyMetatable = { __index = print } setmetatable(MyTable, MyMetatable) MyTable.NilValue('wideseal') -- prints wideseal
This will print because __index
in this case refers to print
, why? Because this is built in metamethod and it fires when you index table which MUST be connected to the metatable with the metamethod. __index
is explained in roblox debhub like this: Fires when table[index] is indexed, if table[index] is nil. You see, if you index the table which is connected to metatable then your table will be connected to all the metamethods that the metatable it is connected to has so in our case it's only __index
, this metamethod fires when indexed table key is nil, in our case i fired NilValue
which is not a valid member of the table but since i indexed nil value, __index
fired and in my case it returned print
function as i set it to it. If you index non-nil value, nothing will happen:
local MyTable = {} local MyMetatable = {} function MyTable.test() print('check') end MyMetatable.__index = MyMetatable.test setmetatable(MyTable, MyMetatable) MyTable.test() -- prints check MyTable.NilValue() -- prints check
Both of these print check
, because test
is not nil and we set __index
to the test
function, that way when you call a nil value, __index
refers to MyMetatable.test
so both the functions are the same. This is why you often see people doing:
MyMetatable.__index = MyMetatable
That way let's say you have some profile
local MyProfile = { Cash = 500, }
You create a new function which will create you a new profile, let's call it new
:
local ProfilerMaker = {} ProfilerMaker.__index = ProfilerMaker function ProfileMaker.new(Name) local NewProfile = { Cash = 500, Name = Name, } return setmetatable(NewProfile, ProfileMaker) end function ProfileMaker:Rob() self.Cash /= 2 -- divide by 2 print(self.Name .. ' has been robbed!') end local MyProfile = ProfileMaker.new('kirda') print(MyProfile.Name) -- kirda print(MyProfile.Cash) -- 500 MyProfile:Rob() -- kirda has been robbed print(MyProfile.Cash) -- 250 print(MyProfile.new == ProfileMaker.new) -- true
Now this may seem compicated but the last can help you understand it, in function new
it created new table and set it's metatable to ProfileMaker
, that way NewProfile
table is connected to all metamethods of ProfileMaker
which there is only one __index
, NewProfile
has it's own stats, Name
and Cash
which are the default values in this case. You see i printed MyProfile.Name
and it returned kirda because it's apart of the table that new
function returns but then i called :Rob()
function which is NOT apart of the NewProfile
BUT it's apart of the ProfileMaker
and since there is __index
and i indexed nil value, it will lead to the __index
value which in this case is ProfileMaker
so it will look for Rob
function inside of the ProfileMaker
which it exists. That way you can call all functions inside of ProfileMaker
but what is self?
In OOP self is very important, i mean... no self no OOP, self = this
in other languages if i am sure but no idea. self
refers to the table itself and in the function Rob
the self
was MyProfile
because i called it with :
which puts self
automatically, let's say those three methods are almost the same (except the last one):
workspace.Destroy(workspace) -- i used `.` so it does not have self, need to put it as the first argument workspace:Destroy() -- normal workspace.Destroy(Instance.new('Part')) -- i also did not use `.` but instead of workspace as self i put new part so this will destroy the newly created part by calling function of workspace
That might be confusing but if you would call MyProfile.Rob()
then self
would refer to the first argument you give you could do MyProfile.Rob(MyProfile)
but you won't because that's the point of OOP
, you can always not use OOP and get good results but OOP is just very comfortable to use.
Sorry the post got too long but here are sources you can read:
The only reason I learned how a metatable worked was through this simple but very teaching variable I found on another script.
This may seem like nothing but it really gets you far into it, I suggest taking some time and looking through other threads through the Developer Forum to get a better grasp on it. Otherwise, the best starting place would be learning about Metatable.__index and Metatable.__newindex most importantly, they are what make up most of the scripting you see.
This will eventually help you learn the other metamethods and it has helped me a lot.
local S = setmetatable({}, {__index = function(self, index) return game:GetService(index) end}) local Players = S.Chat -- aka game:GetService("Players")
I can guess why you find them very useful, they are. I hope you take this answer and find the time to research them, they aren't as bad as they seem.
These will confuse you, as they did to me. There's not really any good tutorial but I could suggest some YouTube tutorials for Lua metatables, the roblox metatable tutorials don't really go in depth from what I've discovered.