El metamétodo __index
Parte de la sección Lógica y flujo de control del Journey de Lua de Coddy — lección 18 de 54.
Ahora que sabes cómo adjuntar metatablas a las tablas, es hora de aprender sobre el metamétodo más importante: __index. Este metamétodo controla lo que sucede cuando intentas acceder a una clave que no existe en una tabla.
Normalmente, cuando buscas una clave que no está en una tabla, Lua devuelve nil. Pero cuando una tabla tiene una metatabla con un campo __index, Lua comprobará ese campo en su lugar. Si __index apunta a otra tabla, Lua buscará la clave allí:
local defaults = {
health = 100,
speed = 10
}
local player = {name = "Alice"}
local meta = {__index = defaults}
setmetatable(player, meta)
print(player.name) -- Salida: Alice
print(player.health) -- Salida: 100En este ejemplo, player solo tiene una clave name. Cuando accedes a player.health, Lua no lo encuentra en player, así que busca en el campo __index de la metatabla. Dado que __index apunta a la tabla defaults, Lua busca allí y encuentra health = 100.
Esto crea un mecanismo de respaldo donde una tabla puede proporcionar valores predeterminados para otra. La tabla original conserva sus propios valores, pero cualquier clave que falte se busca automáticamente en la tabla de respaldo.
Desafío
FácilEscribe una función createCharacterWithDefaults que tome name y level y devuelva una tabla de personaje con valores de estadísticas predeterminados.
Crea una tabla de personaje con el nombre y nivel proporcionados. Usa una metatabla con __index para proporcionar valores predeterminados para cualquier estadística faltante (health, mana, strength).
Lógica:
- Crea una tabla de valores predeterminados con las claves:
health = 100,mana = 50,strength = 10 - Crea una tabla de personaje con las claves:
name(el nombre proporcionado) ylevel(el nivel proporcionado) - Crea una metatabla con
__indexapuntando a la tabla de valores predeterminados - Adjunta la metatabla a la tabla de personaje usando
setmetatable() - Devuelve la tabla de personaje
Parámetros:
name(string): El nombre del personajelevel(number): El nivel del personaje
Devuelve: Una tabla de personaje con name, level y estadísticas predeterminadas accesibles a través de la metatabla (table)
Pruébalo tú mismo
function createCharacterWithDefaults(name, level)
-- Escribe el código aquí
end
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Lógica y flujo de control
1Iteración avanzada de tablas
Iterar con pairs()Iterar con ipairs()pairs() vs. ipairs()Resumen - Ficha de personaje4Introducción a las Metatablas
¿Qué es una Metatabla?setmetatable y getmetatableEl metamétodo __indexEl metamétodo __newindexEl metamétodo __tostringMetamétodos aritméticos - Parte 1Metamétodos aritméticos - Parte 2Resumen - Tablas de solo lectura2Más funciones de la librería table
table.concat()Construcción de tablas y unpack()table.sort()Ordenamiento personalizado con funcionesRepaso - Tabla de puntuaciones altas