Understanding Metatables

https://developer.roblox.com/en-us/articles/Metatables Hello, I searched here, and here What are metatables for and how to understand them? , and here All about Object Oriented Programming , I just do not understand what the use for, its like, making a table but with more information or…?? I don’t get it! All the examplse areind of complicated, and I speak spanish tho, can you just give me a really simple text explaining what it does or how to use it, or for what!! It’s like making 2 tables in 1?

Metatables allow you to use operators on tables, for example
a + b (__add metamethod)
or modify the existing ones
a[1] (if a[1] is nil then __index metamethod will be fired, and you can assign your own function to it)

for example you can modify the __newindex metamethod to make the table read-only (you can still set its values using rawset, so if you really want to make a read-only object check out newproxy function)

local a = setmetatable({}, __newindex = function() error("Attempt to modify read-only table.") end)
a[3] = 3 -- error

What happens inside is that you still have a copy of your original table and a metatable assigned to it. You can still put values/references in your table or in the metatable.

local originalTable = {x = 5}
local metatable = {}
a = setmetatable(originalTable, metatable) -- a is a copy of originalTable with a metatable assigned to it
a[1] = 5 -- sets value 5 to index 1 in a
getmetatable(a)[1] = 5 -- sets value 5 to index 1 in the metatable
2 Likes

Metatables are mostly used for creating your own classes. You can even make your own string or Vector class:

String class example:

local STRING = {}
local mt = {}

-- __add fires whenever the addition operator (+) is called
function mt:__add(s)
    return newstring(self.str .. s.str)
end

-- __tostring fires when tostring() is called, and tostring() is called when you call print.
function mt:__tostring()
    return self.str
end

function newstring(str)
    local tbl = {}
    tbl.str = str
    return setmetatable(tbl, mt)
end

local s1 = newstring("hello")
local s2 = newstring(" ")
local s3 = newstring("world")

print(s1 + s2 + s3) -- hello world

Vector class example:

local Vector = {}
local mt = {}

function Vector.new(x, y)
   local tbl = {}
   tbl.x = x
   tbl.y = y
   return setmetatable(tbl, mt)
end

function mt.__add(a, b)
    return Vector.new(a.x + b.x, a.y + b.y)
end

function mt:__tostring()
    return self.x .. ", " .. self.y
end

local a = Vector.new(10, 10)
local b = Vector.new(5, 2)

print(a + b)
1 Like

But for what would I use it for?

You can use metatables to create classes to make a purpose easier. You can make a class for quaternions to be used instead of Euler angles to represent orientation in a 3D space and you won’t have to deal with gimbal lock. You can use metatables to make an inventory manager, where you can add items using the addition operator (+) and remove items using the subtraction operator (-)

1 Like

You can think of a metatable as a list of events for another table. These events are known as metamethods and run when something specific happens, like if you try to do table + table. By making your own metamethods you can change how something like table + table works to suit your needs instead of just giving an error.

Ohh! I think I now kind of understand it, I will do somet testing

I think metatables are mostly used because of this reason

For example, having 2 modules one named TrainClass and another named TrainSuperClass in TrainClass module you store properties of the train for example Speed, Carriages count, Textures and a lot more and in the TrainSuperClass you apply these properties to the train.

Starter

TrainClass

TrainSuperClass

1 Like