Understanding Metatables

Hello! Welcome to my tutorial about Lua Metatables. Let’s begin!

What is a metatable

I recommend thinking of metatables as more powerful tables. With a lot more operations
compared to a normal table, like arithmetic, tostring, and more!

Image by @BenSBk

How do you set a metatable to a table

To set a metatable to a table, we’ll use setmetatable().
It requires 2 arguments: The table you want to attach the metatable to, and the metatable.
Example code:

local normalTable = {};

local metametable = {};

setmetatable(normalTable, metamethod)

Know that putting setmetatable() in a variable returns the table that you wanted to attach the metatable to. Example:

local meta = setmetatable({Lol = 15}, {}) -- Returns the first argument (the table you want to attach the metatable to.)

print(meta.Lol) -- Prints 15

Metamethods and how you set them

You can think of metamethods just like events! In Roblox, whenever you have a part for example, and you detect .Touched event, it of course fires each time the part is touched, so, metamethods invoke whenever something happens in the table. Like indexing a key that does not exist (__index), trying to change a value of a key that does not exist (__newindex), etc. Metamethods have 2 underscores before their metamethod’s name, always remember to put them: __
How do you set a metamethod to the metatable?
Example code:

local normalTable = {};

local metatable = {} -- Metatables are normal tables, with metamethods inside.
metatable.__index = function(tab, key)

    return key.. " was not found in table."
end

setmetatable(normalTable, metatable)

You can also retrun a table, so, if the metamethod invokes,
it does a ‘re-check’ on table that you return. Example:

local normalTable = {};

local metatable = {}
metatable.__index = {Value = 5} -- Returns this table and does a 're-check' on it.

setmetatable(normalTable, metatable)

print(normalTable.Value) -- Prints 5, as it exists in the table that we returned.

When each metamethod invokes


You’ll mostly be using the __index and __newindex metamethods, others for specific cases.

(The metamethods chart can be found here)

What is getmetatable()?

As I reminded in the code above, when you put setmetatable() in a variable, it returns the first argument (the table). Now, how can you get the metatable? You will use getmetatable().
Example code:

local normalTable = {};

local meta = setmetatable(normalTable, {})

local metatable = getmetatable(meta) -- Returns the second argument (the metatable).

metatable.__index = function(tab, key) -- Adding the metamethod to the metatable.
   return key -- Instead of returning nil, it returns the key that was tried to index.
end

print(normalTable.lol) -- Prints lol!

Another example:

local normalTable = {Username = "XDvvvDX"}; 

local meta = setmetatable(normalTable, {});

local metatable = getmetatable(meta); -- Returns the second argument (the metatable).

metatable.__tostring = function(tab) -- __tostring returns the table.
	return tab.Username
end

print(tostring(normalTable)) -- Prints XDvvvDX!

Userdatas & Proxies

Instead of using setmetatable(), you can use userdatas.
Userdatas are used mostly to bypass metamethods that are not supported
by the version of Lua that Roblox is using (try to print _VERSION).
You’ll use newproxy(), which creates a new proxy, and then
you can get it’s metatable using getmetatable().
Example code:

local userData = newproxy(true); -- Setting it to true so it's metatable is editable.

local metatable = getmetatable(userData) -- Getting the metatable.
metatable.__len = function(tab) -- The __len metamethod isn't supported.
	return math.pi
end

print(#userData) -- Prints the value of pi!

Use cases of metatables

Metatables are especially used in Oriented Object Programming, and it is very important
to understand before dealing with Oriented Object Programming.

Recommended sources to learn metatables from

If you read this post until the end, and did not understand metatable still, I recommend looking at these sources that may help you:

Metatables explanation by ScriptGuider

Metatables explanation by AlvinBlox

Metatables community tutorial by @starmaq

If you have any questions or mistakes you’ve found in my post, feel free to ask in the comment section of this post. Thank you! :slight_smile:

5 Likes

Very well explained. I was wondering what the uses of metables were and how I could use them. Your thread explained it well for metable beginners like me. If possible, could you provide a link to the metamethod chart?

1 Like

I am glad that you liked this tutorial, the metamethods chart can be found here.

1 Like

Wonderful tutorial!! I was confused about something, but not anymore! Thanks @XDvvvDx my friend

1 Like

Thank you! Glad that it helped. :slight_smile:

1 Like

Just so you do know. __len meta method will not work on a normal table once you set the meta method. Roblox’s Lua Version does;t support it. However to bypass this you’d use a proxy and set the table of that.

You also forgot that calling getmetatable on a table with the __metatable meta method will return whatever value the __metamathod is or an possible error.

You could of added a unique section about proxies and userdata.

local moduleOrTable = {}

local proxy = newproxy(true) -- true so we can edit userdata metatable
local proxyMetatable = getmetatable(proxy)

proxyMetatable.__index = moduleOrTable
proxyMetatable.__newindex = moduleOrTable 
proxyMetatable.__tostring = function() return script.Name end

return proxy
1 Like

Thank you for telling! I am adding a section about it at the moment.

Search before posting: All you need to know about Metatables and Metamethods