Metatabelas permitem personalizar o comportamento das tabelas em Lua. Toda tabela pode receber, via setmetatable, uma segunda tabela — a metatabela — cujos campos especiais (metamétodos, sempre com o prefixo __) dizem ao interpretador o que fazer em situações que a tabela sozinha não saberia resolver: somar duas tabelas, converter para texto, tratar acesso a chaves inexistentes, ser chamada como função etc. É o mecanismo que sustenta operadores personalizados, herança e POO em Lua.
local t = setmetatable({}, { __tostring = function() return "olá!" end })
print(t) --> olá!
| Metamétodo | O que personaliza | Arquivo |
|---|---|---|
__add |
Operador + (soma pura, sem mutar os operandos) |
metatabela.lua |
__eq, __lt, __le |
Comparações ==, <, <= (e as derivadas ~=, >, >=) |
comparacao.lua |
__len |
Operador # |
tamanho_e_concatenacao.lua |
__concat |
Operador .. (e a armadilha da associatividade à direita) |
tamanho_e_concatenacao.lua |
__tostring |
Conversão para texto (print/tostring) |
tostring.lua, metatabela.lua |
__index (tabela) |
Leitura de chave inexistente (herança/somente leitura) | somente_leitura.lua |
__index (função) |
Leitura interceptada: valores sob demanda e proxy completo | indice_como_funcao.lua |
__newindex |
Escrita de chave inexistente (bloqueio/interceptação) | somente_leitura.lua, tabela_proxy.lua, indice_como_funcao.lua |
__call |
Chamar a tabela como se fosse uma função | chamada.lua |
__close |
Variáveis to-be-closed (local x <close>, Lua 5.4) |
finalizadores.lua |
__gc |
Finalizadores executados pelo coletor de lixo | finalizadores.lua |
Outros metamétodos relacionados aparecem em outras pastas: __mode (tabelas fracas) em ../gc/ e o uso de __index para classes em ../poo/.