I've tried looking everywhere, and read quite a few in depth tutorials on how to use metatables, and that they're pretty powerful, but it's so confusing for me. I went to the roblox wiki and the keys and metamethods just confused me, I just don't understand it. I only know about how metatables can return something other than nil from: ~~~~~~~~~~~~~~~~~ t = {"hi", "hello"} print(t[3]) ~~~~~~~~~~~~~~~~~ And it sounds pretty cool but whenever I look at code for it, I can't understand it.
Let's say you're given any normal standard table - call it tab1
. Given any table, a metatable is just a secondary table attached to it. With the exception of tab1 being indexed with a normal existing key, Lua will try to fall back to a metatable if there is one.
local tab1 = {a=1} local meta = {} --this doesn't do anything yet setmetatable(tab1,meta) print(tab1.a) --will not attempt to use meta print(tab1.b) --will attempt to use meta (again does nothing yet tho)
The confusing part is the special "metamethod" stuff. The only useful keys/indexes to give a metatable are metamethods. They behave like magic events when certain operators are attempted on tab1.
By "fall back" I did not mean Lua will simply index "meta" instead; Lua invokes a certain metamethod based on what operation you tried to do. In the example above, the operation would have been __index. Because I tried to index "b". Now what about the resulting value?
--btw setmetatable returns tab1- so you can condense the first 3 lines local tab1 = setmetatable( {a=1} , {__index=2} ) print(tab1.a) --will not attempt to use meta --> 1 print(tab1.b) --invokes metamethod __index --> ERROR: attempt to index a number value
Not cool, but proves a point. metamethods never simply return the set value. Lua replaced tab1.b
with 2.b
. Fix:
local tab1 = setmetatable( {a=1} , {__index=function() return 2 end} ) print(tab1.a) --will not attempt to use meta --> 1 print(tab1.b) --invokes metamethod __index --> 2
Cool right? One more example. Normally tostring(tab1)
would return something like table: 12ABC34D
. Let's say you want it to return something else. In any other language it is impossible but in Lua there is a metamethod!
local tab1 = setmetatable( {a=1} , {__tostring = function() return "Hello world!" end} ) print(tab1) --> Hello world!
Do not try to wrap your head around why it works lol. It's abstracted magic. This is as far as I will go because its not an article. Here are articles:
http://wiki.roblox.com/index.php?title=Metatable#Metamethods https://devforum.roblox.com/t/all-about-object-oriented-programming/8585