Menu
Coddy logo textTech

Tabelas Somente Leitura

Parte da seção Programação Orientada a Objetos do Journey de Lua da Coddy. Lição 46 de 70.

Closures fornecem privacidade verdadeira, mas exigem a definição de métodos dentro do construtor. Há outra abordagem para um caso de uso diferente: tornar um objeto somente leitura após a criação. Isso é útil quando você quer que os campos sejam visíveis, mas imutáveis, como as coordenadas de um ponto fixo.

O metamétodo __newindex intercepta tentativas de atribuir novos valores a uma tabela. Ao fazê-lo bloquear todas as atribuições, você pode congelar um objeto:

local ImmutablePoint = {}

function ImmutablePoint.new(x, y)
    local data = {x = x, y = y}
    
    local proxy = {}
    setmetatable(proxy, {
        __index = data,
        __newindex = function()
            error("Cannot modify immutable object")
        end
    })
    
    return proxy
end

O truque é usar uma tabela proxy. Os dados reais ficam em data, enquanto o usuário interage com a proxy vazia.

Ao ler, __index busca em data. Ao escrever, __newindex é acionado em vez disso, e nós o bloqueamos:

local p = ImmutablePoint.new(10, 20)
print(p.x)  -- 10 (leitura funciona)
p.x = 50    -- Erro: Não é possível modificar objeto imutável

Esse padrão é valioso para objetos de configuração, constantes matemáticas ou quaisquer dados que nunca devam mudar após a inicialização. O objeto permanece totalmente legível. Você simplesmente não pode alterá-lo.

challenge icon

Desafio

Fácil

Vamos criar uma classe ImmutableConfig que cria objetos de configuração somente leitura! Depois de criados, esses objetos de configuração devem permitir a leitura de suas configurações, mas bloquear completamente qualquer tentativa de modificá-las.

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

  • ImmutableConfig.lua: crie um módulo que produza objetos de configuração congelados. Sua função .new(appName, version, maxUsers) deve armazenar esses três valores internamente e, em seguida, retornar uma tabela proxy que permita ler todos os campos, mas impeça qualquer modificação. Quando alguém tentar alterar um valor, deve imprimir Error: Config is read-only em vez de gerar um erro de fato.
  • main.lua: coloque seu ImmutableConfig em funcionamento! Leia três entradas para os valores de configuração, crie um objeto de configuração e demonstre que ele funciona corretamente:
    • Imprima os três valores originais
    • Tente modificar o campo maxUsers (o que deve disparar a mensagem de erro)
    • Imprima maxUsers novamente para provar que ele não foi realmente alterado

Você receberá três entradas:

  1. O nome da aplicação (uma string)
  2. A versão (uma string)
  3. O número máximo de usuários (um número)

Sua saída deve mostrar os valores da configuração, o erro quando a modificação for tentada e a confirmação de que o valor permaneceu inalterado:

App: {appName}
Version: {version}
Max Users: {maxUsers}
Error: Config is read-only
Max Users: {maxUsers}

Por exemplo, se as entradas forem MyApp, 2.0 e 100, a saída deverá ser:

App: MyApp
Version: 2.0
Max Users: 100
Error: Config is read-only
Max Users: 100

Lembre-se: o padrão proxy usa uma tabela vazia com a qual o usuário interage, enquanto os dados reais ficam em uma tabela interna separada. O metamétodo __index busca dados na tabela de dados, e __newindex intercepta (e bloqueia) qualquer tentativa de escrita!

Experimente você mesmo

-- Importar o módulo ImmutableConfig
local ImmutableConfig = require('ImmutableConfig')

-- Ler as entradas
local appName = io.read()
local version = io.read()
local maxUsers = tonumber(io.read())

-- TODO: Crie um objeto de configuração usando ImmutableConfig.new()

-- TODO: Imprima todos os três valores originais no formato:
-- App: {appName}
-- Version: {version}
-- Max Users: {maxUsers}

-- TODO: Tente modificar o campo maxUsers (isso deve acionar a mensagem de erro)

-- TODO: Imprima maxUsers novamente para provar que não foi alterado
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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de Lua online