Menu
Coddy logo textTech

Concatenar objetos

Parte de la sección Object Oriented Programming del Journey de Lua de Coddy — lección 28 de 70.

El operador .. en Lua concatena cadenas, ¿pero qué pasa si quieres combinar un objeto con una cadena? El metamétodo __concat te permite definir exactamente cómo debería funcionar esto.

Cuando Lua encuentra a .. b y un operando tiene un metamétodo __concat, llama a esa función con ambos valores. Esto es útil cuando quieres que los objetos se integren de forma natural en expresiones de cadena.

local Name = {}
Name.__index = Name

function Name:new(first, last)
    local obj = {first = first, last = last}
    setmetatable(obj, Name)
    return obj
end

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

Observa que la función comprueba qué operando es la cadena. Dado que .. se puede usar como "Hello " .. obj o obj .. "!", tu metamétodo debería manejar ambos casos.

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- Salida: Dr. Ada Lovelace
print(person .. " PhD")      -- Salida: Ada Lovelace PhD

Al igual que otros metamétodos de operador, __concat utiliza la sintaxis de punto y recibe ambos operandos como argumentos. La diferencia clave con respecto a los metamétodos aritméticos es que normalmente se trabaja con tipos mixtos: su objeto y una cadena.

challenge icon

Desafío

Fácil

Vamos a construir una clase Title que pueda integrarse de forma natural en expresiones de cadena utilizando el operador ... Esto es útil cuando deseas combinar objetos con cadenas de una manera legible e intuitiva, como al añadir honoríficos o sufijos al título de una persona.

Organizarás tu código en dos archivos:

  • Title.lua: Define tu clase Title con un campo text que almacene la cadena del título. Incluye un constructor :new(text) e implementa el metamétodo __concat. Tu metamétodo debe manejar ambos casos: cuando una cadena va antes del objeto ("prefix" .. obj) y cuando una cadena va después (obj .. "suffix"). El resultado debe combinar la cadena con el texto del título de manera apropiada.
  • main.lua: Requiere tu módulo Title, crea una instancia de title y demuestra la concatenación desde ambas direcciones.

Recibirás tres entradas:

  1. El texto del título (por ejemplo, "Engineer")
  2. Una cadena de prefijo para colocar antes del título (por ejemplo, "Senior ")
  3. Una cadena de sufijo para colocar después del título (por ejemplo, " III")

En tu archivo principal, crea un Title con el texto dado. Luego realiza dos concatenaciones e imprime cada resultado en una línea separada:

  1. Concatena la cadena de prefijo con el objeto title
  2. Concatena el objeto title con la cadena de sufijo

Por ejemplo, si las entradas son Engineer, Senior , y III, la salida debería ser:

Senior Engineer
Engineer III

La primera línea muestra el prefijo combinado con el título, y la segunda línea muestra el título combinado con el sufijo. ¡Tu metamétodo __concat hace posible esta combinación natural de cadenas!

Hoja de referencia

El metamétodo __concat te permite definir un comportamiento personalizado para el operador de concatenación .. cuando trabajas con objetos.

Cuando Lua encuentra a .. b y uno de los operandos tiene un metamétodo __concat, llama a esa función con ambos valores.

Implementación básica

local MyClass = {}
MyClass.__index = MyClass

function MyClass:new(value)
    local obj = {value = value}
    setmetatable(obj, MyClass)
    return obj
end

function MyClass.__concat(a, b)
    if type(a) == "string" then
        return a .. b.value
    else
        return a.value .. b
    end
end

Manejo de ambos órdenes de operandos

Dado que .. se puede usar como "string" .. obj o obj .. "string", tu metamétodo debe verificar qué operando es la cadena y manejar ambos casos:

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

Ejemplo de uso

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- Salida: Dr. Ada Lovelace
print(person .. " PhD")      -- Salida: Ada Lovelace PhD

Al igual que otros metamétodos de operador, __concat utiliza la sintaxis de punto y recibe ambos operandos como argumentos.

Pruébalo tú mismo

-- Leer entradas
local titleText = io.read()
local prefix = io.read()
local suffix = io.read()

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

-- TODO: Crear una instancia de Title con el titleText dado

-- TODO: Concatenar el prefijo con el objeto title e imprimir el resultado

-- TODO: Concatenar el objeto title con el sufijo e imprimir el resultado
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 Object Oriented Programming