El metamétodo __index
Parte de la sección Lógica y flujo 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á allí la clave:
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 la encuentra en player, así que comprueba el campo __index de la metatabla. Como __index apunta a la tabla defaults, Lua busca allí y encuentra health = 100.
Esto crea un mecanismo alternativo en el que 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 alternativa.
__index también puede ser una función. Cuando falta una clave, Lua la llama con la tabla y la clave, y utiliza lo que devuelva:
local scores = {alice = 12}
setmetatable(scores, {
__index = function(t, key)
return 0 -- cada nombre que no exista cuenta como 0
end
})
print(scores.alice) -- Salida: 12
print(scores.bob) -- Salida: 0Una tabla proporciona valores alternativos fijos; una función puede calcular un valor para cualquier clave que falte.
Desafío
FácilEscribe una función createCharacterWithDefaults que reciba name y level y devuelva una tabla de personaje con valores de estadísticas predeterminados.
Crea una tabla de personaje con el nombre y el nivel proporcionados. Usa una metatabla con __index para proporcionar valores predeterminados para cualquier estadística que falte (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 - Asocia la metatabla a la tabla de personaje usando
setmetatable() - Devuelve la tabla de personaje
Parámetros:
name(cadena): El nombre del personajelevel(número): El nivel del personaje
Devuelve: Una tabla de personaje con el nombre, el nivel y las estadísticas predeterminadas accesibles a través de la metatabla (tabla)
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
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 altasPractica por tu cuenta: Compilador de Lua online