Menu
Coddy logo textTech

Tablas de solo lectura

Parte de la sección Programación Orientada a Objetos del Journey de Lua de Coddy. Lección 46 de 70.

Las clausuras proporcionan privacidad real, pero requieren definir métodos dentro del constructor. Existe otro enfoque para un caso de uso diferente: hacer que un objeto sea de solo lectura después de su creación. Esto resulta útil cuando quieres que los campos sean visibles pero inmodificables, como las coordenadas de un punto fijo.

El metumétodo __newindex intercepta los intentos de asignar nuevos valores a una tabla. Al hacer que bloquee todas las asignaciones, puedes congelar un 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

El truco consiste en usar una tabla proxy. Los datos reales se encuentran en data, mientras que el usuario interactúa con el proxy vacío.

Al leer, __index obtiene datos de data. Al escribir, se activa __newindex en su lugar y lo bloqueamos:

local p = ImmutablePoint.new(10, 20)
print(p.x)  -- 10 (la lectura funciona)
p.x = 50    -- Error: No se puede modificar un objeto inmutable

Este patrón es valioso para objetos de configuración, constantes matemáticas o cualquier dato que nunca deba cambiar después de la inicialización. El objeto sigue siendo completamente legible. Simplemente no puedes modificarlo.

challenge icon

Desafío

Fácil

¡Construyamos una clase ImmutableConfig que cree objetos de configuración de solo lectura! Una vez creados, estos objetos de configuración deberían permitir leer sus ajustes, pero bloquear por completo cualquier intento de modificarlos.

Organizarás tu código en dos archivos:

  • ImmutableConfig.lua: Crea un módulo que produzca objetos de configuración congelados. Tu función .new(appName, version, maxUsers) debe almacenar internamente estos tres valores y, después, devolver una tabla proxy que permita leer todos los campos, pero impida cualquier modificación. Cuando alguien intente cambiar un valor, debe imprimir Error: Config is read-only en lugar de generar un error real.
  • main.lua: ¡Pon en marcha tu ImmutableConfig! Lee tres entradas para los valores de configuración, crea un objeto de configuración y, después, demuestra que funciona correctamente:
    • Imprimiendo los tres valores originales
    • Intentando modificar el campo maxUsers (lo que debería activar el mensaje de error)
    • Imprimiendo maxUsers de nuevo para demostrar que en realidad no cambió

Recibirás tres entradas:

  1. El nombre de la aplicación (una cadena)
  2. La versión (una cadena)
  3. El número máximo de usuarios (un número)

Tu salida debe mostrar los valores de configuración, el error cuando se intenta modificarla y la confirmación de que el valor permaneció sin cambios:

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

Por ejemplo, si las entradas son MyApp, 2.0 y 100, la salida debería ser:

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

Recuerda: el patrón proxy utiliza una tabla vacía con la que interactúa el usuario, mientras que los datos reales viven en una tabla interna separada. El metamétodo __index obtiene los datos de la tabla de datos, y __newindex intercepta (y bloquea) cualquier intento de escritura.

Pruébalo tú mismo

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

-- Leer las entradas
local appName = io.read()
local version = io.read()
local maxUsers = tonumber(io.read())

-- TODO: Crear un objeto config usando ImmutableConfig.new()

-- TODO: Imprimir los tres valores originales en el formato:
-- App: {appName}
-- Version: {version}
-- Max Users: {maxUsers}

-- TODO: Intentar modificar el campo maxUsers (esto debería activar el mensaje de error)

-- TODO: Imprimir maxUsers de nuevo para demostrar que no se modificó
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

Practica por tu cuenta: Compilador de Lua online