Skip to content
OOP via __index
step 1/4

Reading — step 1 of 4

Learn

~1 min readMetatables and OOP

__index is the metamethod that fires on missing key lookup. It's the foundation of Lua-style OO.

-- Define a "class" — really just a table
local Animal = {}
Animal.__index = Animal     -- self-reference: missing keys fall back here

function Animal.new(name, sound)
    local self = setmetatable({}, Animal)
    self.name = name
    self.sound = sound
    return self
end

function Animal:describe()  -- colon syntax: implicit self
    return self.name .. " says " .. self.sound
end

local cat = Animal.new("Whiskers", "meow")
print(cat:describe())       -- "Whiskers says meow"

The colon trick: obj:method(args) is sugar for obj.method(obj, args). Inside function T:method(), self is implicit — the first argument is filled in.

When cat:describe() runs:

  1. Lua looks up describe on cat — not there
  2. Falls back to cat's metatable's __index
  3. __index = Animal → finds Animal.describe
  4. Calls it with cat as the implicit self

Inheritance — a class table whose __index points to its parent:

local Dog = setmetatable({}, {__index = Animal})
Dog.__index = Dog

function Dog.new(name)
    local self = Animal.new(name, "woof")
    return setmetatable(self, Dog)
end

function Dog:fetch()
    return self.name .. " fetches the ball"
end

local rex = Dog.new("Rex")
print(rex:describe())   -- inherited from Animal
print(rex:fetch())       -- defined on Dog

This is verbose but transparent. Many Lua frameworks (LÖVE, Roblox) provide class() helpers, but they all reduce to this pattern.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…

OOP via __index — Lua Intermediate