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: 100In 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: 0A table gives fixed fallback values; a function can work out a value for any missing key.
Challenge
EasyWrite 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) andlevel(the provided level) - Create a metatable with
__indexpointing to the defaults table - Attach the metatable to the character table using
setmetatable() - Return the character table
Parameters:
name(string): The character's namelevel(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
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Advanced Table Iteration
Iterating with pairs()Iterating with ipairs()pairs() vs. ipairs()Recap - Character Sheet4Introduction to Metatables
What is a Metatable?setmetatable & getmetatableThe __index MetamethodThe __newindex MetamethodThe __tostring MetamethodArithmetic Metamethods Part 1Arithmetic Metamethods Part 2Recap - Read-Only Table2More Table Library Functions
table.concat()table construction & unpack()table.sort()Custom Sorting with FunctionsRecap - High Score BoardPractice on your own: Online Lua compiler