Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How do metatables work (game metatables?)

Asked by
trecept 367 Moderation Voter
6 years ago

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.

1 answer

Log in to vote
0
Answered by
cabbler 1942 Moderation Voter
6 years ago

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?

  • 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.
--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

Ad

Answer this question