How do I use metatables?

I have a question. I know about the existence of metatables, but I don’t know:

  1. How to use them
  2. Where should I apply them

If you can answer one or both of these questions, that would help me quite a lot!

Metatables give more functionality to a regular table. Metatables take one table and merge/connect it with a regular table.

Metatables use Metamethods.
__index is a popular one, in a metatable, it would look like this:

local meta = {
__index = function(t, i)
 print(i)
end,
}

__index is fired when a table gets indexed, but the index was nil.

In order to connect a metatable to a table, you need to use setmetatable(table, table).

Here is an example:

local meta = {
  __index = function(t, i)
    print("index was nil! " .. tostring(i))
 end,
}

local regular_table = {5,2,1}

setmetatable(regular_table, meta)
print(regular_table[3]) -- > 1

print(regular_table[5]) -- > "index was nil! 5
print(regular_table[1]) -- > 5

etc.

Here is the documentations, with other metamethods.

Sorry for asking, what is

__index

really mean?

Also, you didn’t really explain why I should use them over just a function…

It’s a metamethod, a popular one. (I used it for that example).

__index is a function that fires when a table gets indexed, but that index is nil/doesn’t exist, and nothing is set there.

So is it for error prevention? Or am I missing something here?

They give tables more functionality, and there is more metamethods than just __index.
It can also be used in Object Orientated Programming, here is a screenshot of the metamethods:

Technically, yes.

Although it can be used for other stuff.

I can’t think of any use cases for this. Could you provide an example?

local tab = {}
local latest_player = nil

setmetatable(tab, {
  __newindex = function(s, i, v)
    if v.ClassName == "Player" then
      latest_player = v
   end
  end
 }
end)

game.Players.PlayerAdded:Connect(function(p)
 tab[(#tab + 1)] = p
end)

if latest_player ~= nil then
  -- do stuff with the latest player
end

Although there is other cases you can use it, it depends on the way you use it.

A big one with a metamethod is __call

This might sound crazy, but it’s a method anyway; you can call tables as functions.