Metatables and Metamethods
Unlock Lua's most powerful feature: customise how tables behave with operator overloading, default values, and OOP patterns.
What You'll Learn
- What metatables are and how setmetatable works
- __index for default values and prototype chains
- Operator overloading with __add, __sub, __eq, __tostring
- Building OOP classes with metatables
What Are Metatables?
A metatable is a regular Lua table that defines special behaviours for another table. When Lua encounters an operation it doesn't know how to perform (like adding two tables), it checks the metatable for a metamethod โ a function that handles that operation.
๐ฎ Real-World Analogy: Think of a metatable like a user manual for a table. The table itself holds your data, but the manual (metatable) tells Lua what to do in special situations โ like "when someone asks for a key that doesn't exist, look it up here instead."
local myTable = {}
local myMeta = {}
setmetatable(myTable, myMeta) -- attach the metatable
getmetatable(myTable) -- returns myMetaKey Metamethods
| Metamethod | Triggered When |
|---|---|
| __index | Accessing a missing key |
| __newindex | Setting a new key |
| __add | The + operator |
| __sub | The - operator |
| __mul | The * operator |
| __eq | The == operator |
| __lt | The < operator |
| __tostring | tostring() or print() |
| __call | Calling table as function |
Metatables in Action
See how __index, __add, and __newindex work.
// Lua Metatables โ simulated in JavaScript
console.log("=== What Are Metatables? ===");
console.log("Metatables let you customise how tables behave.");
console.log("They intercept operations like +, -, [], tostring.");
console.log();
console.log("=== __index: Default Values ===");
// Simulating __index metamethod
const defaults = { color: "red", speed: 10, health: 100 };
const player = new Proxy({name: "Hero", speed: 25}, {
get(target, prop) {
return prop in target ? target[prop] : defau
...OOP with Metatables
Lua doesn't have a class keyword, but you can build a full OOP system using metatables. The pattern is elegant and used everywhere in Lua game development.
-- Define a "class"
local Animal = {}
Animal.__index = Animal
function Animal:new(name, sound)
local instance = setmetatable({}, self)
instance.name = name
instance.sound = sound
return instance
end
function Animal:speak()
return self.name .. " says " .. self.sound .. "!"
end
-- Inheritance
local Dog = setmetatable({}, {__index = Animal})
Dog.__index = Dog
function Dog:new(name)
local instance = Animal.new(self, name, "Woof")
instance.tricks = {}
return instance
end
function Dog:learnTrick(trick)
table.insert(self.tricks, trick)
end
-- Usage
local rex = Dog:new("Rex")
print(rex:speak()) -- "Rex says Woof!"
rex:learnTrick("sit")โ ๏ธ Common Mistake
Don't confuse . and : โ the colon (:) automatically passes self as the first argument. dog:speak() is equivalent to dog.speak(dog).
OOP Pattern
Build classes with inheritance using metatables.
// Lua OOP with Metatables โ simulated in JavaScript
console.log("=== OOP Pattern in Lua ===");
console.log("Lua has no 'class' keyword โ use metatables!");
console.log();
// Simulating Lua's OOP pattern
class Animal {
constructor(name, sound) {
this.name = name;
this.sound = sound;
}
speak() {
return this.name + " says " + this.sound + "!";
}
}
class Dog extends Animal {
constructor(name) {
super(name, "Woof");
this.tricks = [];
}
learnTrick(trick) {
this
...๐ก Pro Tip
The __index metamethod can be either a table (for prototype-style lookups) or a function (for computed/dynamic values). Using a function gives you full control over what happens when a missing key is accessed.
๐ Quick Reference
| Concept | Syntax |
|---|---|
| Set metatable | setmetatable(t, mt) |
| Get metatable | getmetatable(t) |
| Default lookup | mt.__index = fallback |
| Method syntax | function T:method() end |
| Constructor | setmetatable({}, {__index = T}) |
๐ Lesson Complete!
You've mastered metatables โ Lua's secret weapon for OOP, operator overloading, and custom behaviours. In the final lesson, we'll apply everything to real game development with LรVE2D and Roblox!
Sign up for free to track which lessons you've completed and get learning reminders.