Metatables. How to use it right?

Hello scripters! I wanna know what metatables are made for? How to use it right and for what?
It may be hard to undesrtand. So I know it’s a ‘Hidden table’, but why it was made?

Metatables, are quite literally, just tables about tables. They control how other tables behave and help you to simplify things.

Here’s a quick example:

local tbl = {
    ["Name"] = "My Table Name"
}

local meta = {
    __tostring = function(self) return self.Name end
}

setmetatable(tbl, meta)
--the __tostring metamethod controls what happens when we try and cast the table to string
--we can simplify our code now, if we only want the table's name:
print(tbl) --> "My Table Name"

Now, you’re probably thinking, “Why is this useful? What can I achieve with metatables?”. Metatables are used for a wide variety of use cases, the main one being mock-OOP (or just referred to as OOP) in Lua. If you want to read about Object-Oriented Programming, you can do so here.

In standard OOP, we would have something like this:

//some pseudocode
class MyClass
    function method()
        print("method called")
    endfunction
endclass

//creating a new object
var Object = new MyClass()
Object.method()

In this scenario, the object has inherited everything from the class, including the method method. But, Lua doesn’t support this. We need to use metatables instead.

There’s a very useful metatable called __index. This is basically used when Lua doesn’t find what it’s looking for in a table. It can either be set to a function or a table, as shown here:

local tbl = {}

local meta = {
    __index = meta, --set __index to the metatable, we can write values there
    example = 3
}

setmetatable(tbl, meta)
print(tbl.example) --> 3
--key "example" was not found in table "tbl", so the metamethod redirected Luau to search the metatable instead

Now, where it’s used in OOP. We can direct objects to the functions of the class so they replicate OOP’s behaviour.

local Class = {}
Class.__index = Class --assign this metamethod so we redirect objects to the metatable

function Class:method() --our method
    print(self.Name.." just ran this method.")
end

function Class.new() --create a new object
    local self = {Name = "Example"}
    setmetatable(self, Class)
    return self
end

--now, in a separate script...
local Class = require(path_to_class)

local Object = Class.new()
print(Object) --> note that "method" won't show up here.
Object:method() --> "Example just ran this method."

Now, this happens because when we look for “method”, it’s not found, so the metatable redirects us to itself, where key “method” is found and then the function is run.

This is one of the most fundamental metamethods for OOP in Lua, but other metamethods like __newindex, __call, __add, __len, etc. can have extremely useful cases. Please let me know if you have any questions, and I hope this helped!

Metamethods:
Metamethods | Documentation - Roblox Creator Hub

1 Like