✓ Accepted answer
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 = {}
setmetatable(tab1,meta)
print(tab1.a)
print(tab1.b)
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?
- When set to any function, invocation calls the function with tab1 as parameter 1.
- When set to any other value, invocation indexes the value instead of tab1.
local tab1 = setmetatable( {a=1} , {__index=2} )
print(tab1.a)
print(tab1.b)
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)
print(tab1.b)
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)
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