Menu
CoddyTech

The __index Metamethod

Part of the Logic & Flow section of Coddy's Lua journey. Lesson 18 of 54.

Now that you know how to attach metatables to tables, it's time to learn about the most important metamethod: __index. This metamethod controls what happens when you try to access a key that doesn't exist in a table.

Normally, when you look up a key that isn't in a table, Lua returns nil. But when a table has a metatable with an __index field, Lua will check that field instead. If __index points to another table, Lua will look for the key there:

local defaults = {
    health = 100,
    speed = 10
}

local player = {name = "Alice"}
local meta = {__index = defaults}

setmetatable(player, meta)

print(player.name)    -- Output: Alice
print(player.health)  -- Output: 100

In this example, player only has a name key. When you access player.health, Lua doesn't find it in player, so it checks the metatable's __index field. Since __index points to the defaults table, Lua looks there and finds health = 100.

This creates a fallback mechanism where one table can provide default values for another. The original table keeps its own values, but any missing keys are automatically looked up in the fallback table.

__index can also be a function. When a key is missing, Lua calls it with the table and the key, and uses whatever it returns:

local scores = {alice = 12}

setmetatable(scores, {
    __index = function(t, key)
        return 0  -- every missing name counts as 0
    end
})

print(scores.alice)  -- Output: 12
print(scores.bob)    -- Output: 0

A table gives fixed fallback values; a function can work out a value for any missing key.

challenge icon

Challenge

Easy

Write a function createCharacterWithDefaults that takes name and level and returns a character table with default stat values.

Create a character table with the provided name and level. Use a metatable with __index to provide default values for any missing stats (health, mana, strength).

Logic:

  • Create a defaults table with keys: health = 100, mana = 50, strength = 10
  • Create a character table with keys: name (the provided name) and level (the provided level)
  • Create a metatable with __index pointing to the defaults table
  • Attach the metatable to the character table using setmetatable()
  • Return the character table

Parameters:

  • name (string): The character's name
  • level (number): The character's level

Returns: A character table with name, level, and default stats accessible through the metatable (table)

Try it yourself

function createCharacterWithDefaults(name, level)
    -- Write code here
end
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Logic & Flow

Practice on your own: Online Lua compiler