Menu
Coddy logo textTech

Concatenando Objetos

Parte da seção Object Oriented Programming do Journey de Lua da Coddy — lição 28 de 70.

O operador .. em Lua concatena strings, mas e se você quiser combinar um objeto com uma string? O metamétodo __concat permite que você defina exatamente como isso deve funcionar.

Quando o Lua encontra a .. b e um operando possui um metamétodo __concat, ele chama essa função com ambos os valores. Isso é útil quando você deseja que objetos se misturem naturalmente em expressões de string.

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

Observe que a função verifica qual operando é a string. Como .. pode ser usado como "Hello " .. obj ou obj .. "!", seu metamétodo deve lidar com ambos os casos.

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

print("Dr. " .. person)      -- Saída: Dr. Ada Lovelace
print(person .. " PhD")      -- Saída: Ada Lovelace PhD

Como outros metamétodos de operador, __concat usa a sintaxe de ponto e recebe ambos os operandos como argumentos. A principal diferença em relação aos metamétodos aritméticos é que você geralmente está trabalhando com tipos mistos — seu objeto e uma string.

challenge icon

Desafio

Fácil

Vamos construir uma classe Title que possa se misturar naturalmente em expressões de string usando o operador ... Isso é útil quando você deseja combinar objetos com strings de uma maneira legível e intuitiva — como adicionar honoríficos ou sufixos ao título de uma pessoa.

Você organizará seu código em dois arquivos:

  • Title.lua: Defina sua classe Title com um campo text que armazena a string do título. Inclua um construtor :new(text) e implemente o metamétodo __concat. Seu metamétodo deve lidar com ambos os casos: quando uma string vem antes do objeto ("prefix" .. obj) e quando uma string vem depois (obj .. "suffix"). O resultado deve combinar a string com o texto do título apropriadamente.
  • main.lua: Importe seu módulo Title, crie uma instância de título e demonstre a concatenação de ambas as direções.

Você receberá três entradas:

  1. O texto do título (ex: "Engineer")
  2. Uma string de prefixo para colocar antes do título (ex: "Senior ")
  3. Uma string de sufixo para colocar depois do título (ex: " III")

No seu arquivo principal, crie um Title com o texto fornecido. Em seguida, realize duas concatenações e imprima cada resultado em uma linha separada:

  1. Concatene a string de prefixo com o objeto title
  2. Concatene o objeto title com a string de sufixo

Por exemplo, se as entradas forem Engineer, Senior , e III, a saída deve ser:

Senior Engineer
Engineer III

A primeira linha mostra o prefixo combinado com o título, e a segunda linha mostra o título combinado com o sufixo. Seu metamétodo __concat torna possível essa mistura natural de strings!

Folha de consulta

O metamétodo __concat permite que você defina um comportamento personalizado para o operador de concatenação .. ao trabalhar com objetos.

Quando o Lua encontra a .. b e um dos operandos possui um metamétodo __concat, ele chama essa função com ambos os valores.

Implementação 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

Lidando com Ambas as Ordens de Operandos

Como o .. pode ser usado como "string" .. obj ou obj .. "string", seu metamétodo deve verificar qual operando é a string e tratar ambos os 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

Exemplo de Uso

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

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

Assim como outros metamétodos de operador, o __concat utiliza a sintaxe de ponto e recebe ambos os operandos como argumentos.

Experimente você mesmo

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

-- Requerer o módulo Title
local Title = require('Title')

-- TODO: Criar uma instância de Title com o titleText fornecido

-- TODO: Concatenar o prefixo com o objeto title e imprimir o resultado

-- TODO: Concatenar o objeto title com o sufixo e imprimir o resultado
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming