Menu
Coddy logo textTech

Vinculación con __index

Parte de la sección Programación Orientada a Objetos del Journey de Lua de Coddy — lección 7 de 70.

Tienes una tabla prototipo con propiedades y métodos, ¿pero cómo haces que un nuevo objeto realmente la use? La respuesta reside en el metamétodo __index.

Cuando accedes a una clave que no existe en una tabla, Lua normalmente devuelve nil. Sin embargo, si la tabla tiene una metatabla con un campo __index, Lua buscará allí en su lugar. Al configurar __index para que apunte a tu prototipo, cualquier clave que falte se encontrará automáticamente en el prototipo:

local Dog = {
    species = "Canis familiaris",
    legs = 4
}

function Dog:bark()
    print("Woof!")
end

-- Crear una instancia vacía
local myDog = {}

-- Enlazarlo al prototipo
setmetatable(myDog, { __index = Dog })

print(myDog.species)  -- Salida: Canis familiaris
myDog:bark()          -- Salida: Woof!

La tabla myDog está completamente vacía, sin embargo, acceder a myDog.species funciona. Cuando Lua no encuentra species en myDog, consulta el __index de la metatabla y lo encuentra en Dog.

Esta es la base de la programación orientada a objetos en Lua. La instancia puede tener sus propios datos únicos, mientras que el comportamiento compartido reside en el prototipo. En la siguiente lección, aprenderás cómo envolver este patrón en una función constructora limpia.

challenge icon

Desafío

Fácil

¡Ahora pongamos en práctica el metamétodo __index! Crearás un prototipo y vincularás una instancia a él, permitiendo que la instancia acceda a propiedades y métodos que no posee directamente.

Organizarás tu código en dos archivos:

  • Robot.lua: Define una tabla prototipo Robot con:
    • Un campo model establecido en "RX-100"
    • Un campo batteryLevel establecido en 100
    • Un método :status() que imprima el estado actual del robot
    Devuelve la tabla al final del archivo.
  • main.lua: Requiere el módulo Robot, luego crea una tabla de instancia vacía y vincúlala al prototipo Robot usando setmetatable con __index. Esto permite que tu instancia vacía acceda a todo lo del prototipo.

Recibirás una entrada: un nombre para asignar a tu instancia de robot.

Después de vincular la instancia al prototipo:

  1. Asigna el nombre de entrada al campo name de tu instancia (esto se vuelve único para la instancia)
  2. Llama al método :status() en tu instancia

Tu método :status() debe imprimir en este formato exacto:

[name] ([model]) - Battery: [batteryLevel]%

Por ejemplo, si la entrada es Sparky, la salida debería ser:

Sparky (RX-100) - Battery: 100%

Observa cómo la instancia tiene su propio name, pero accede a model y batteryLevel desde el prototipo a través del enlace __index.

Pruébalo tú mismo

-- Leer entrada
local name = io.read()

-- Requerir el módulo Robot
local Robot = require('Robot')

-- TODO: Crear una tabla de instancia vacía

-- TODO: Vincular la instancia al prototipo Robot usando setmetatable con __index

-- TODO: Asignar el nombre de entrada al campo name de tu instancia

-- TODO: Llamar al método :status() en tu instancia
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos