Menu
Coddy logo textTech

Tabelle di sola lettura

Fa parte della sezione Programmazione orientata agli oggetti del percorso Lua di Coddy. Lezione 46 di 70.

Le closure garantiscono una vera privacy, ma richiedono di definire i metodi all'interno del costruttore. Esiste un altro approccio per un caso d'uso diverso: rendere un oggetto di sola lettura dopo la creazione. È utile quando vuoi che i campi siano visibili ma non modificabili, come le coordinate di un punto fisso.

Il metametodo __newindex intercetta i tentativi di assegnare nuovi valori a una tabella. Facendogli bloccare tutte le assegnazioni, puoi congelare un oggetto:

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

Il trucco consiste nell'usare una tabella proxy. I dati effettivi si trovano in data, mentre l'utente interagisce con la proxy vuota.

In lettura, __index recupera i dati da data. In scrittura, invece, viene attivato __newindex e lo blocchiamo:

local p = ImmutablePoint.new(10, 20)
print(p.x)  -- 10 (la lettura funziona)
p.x = 50    -- Errore: impossibile modificare un oggetto immutabile

Questo schema è utile per gli oggetti di configurazione, le costanti matematiche o qualsiasi dato che non dovrebbe mai cambiare dopo l'inizializzazione. L'oggetto rimane completamente leggibile. Semplicemente, non puoi modificarlo.

challenge icon

Sfida

Facile

Costruiamo una classe ImmutableConfig che crea oggetti di configurazione di sola lettura! Una volta creati, questi oggetti di configurazione dovrebbero consentire di leggere le impostazioni, ma bloccare completamente qualsiasi tentativo di modificarle.

Organizzerai il codice in due file:

  • ImmutableConfig.lua: crea un modulo che produce oggetti di configurazione immutabili. La funzione .new(appName, version, maxUsers) dovrebbe memorizzare internamente questi tre valori, quindi restituire una tabella proxy che consente di leggere tutti i campi ma impedisce qualsiasi modifica. Quando qualcuno tenta di modificare un valore, dovrebbe stampare Error: Config is read-only invece di generare un errore effettivo.
  • main.lua: dai vita a ImmutableConfig! Leggi tre input per i valori di configurazione, crea un oggetto di configurazione, quindi dimostra che funziona correttamente:
    • Stampando tutti e tre i valori originali
    • Tentando di modificare il campo maxUsers (che dovrebbe attivare il messaggio di errore)
    • Stampando di nuovo maxUsers per dimostrare che non è stato effettivamente modificato

Riceverai tre input:

  1. Il nome dell'applicazione (una stringa)
  2. La versione (una stringa)
  3. Il numero massimo di utenti (un numero)

L'output dovrebbe mostrare i valori di configurazione, l'errore quando si tenta di modificarli e la conferma che il valore è rimasto invariato:

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

Per esempio, se gli input sono MyApp, 2.0 e 100, l'output dovrebbe essere:

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

Ricorda: il pattern proxy usa una tabella vuota con cui interagisce l'utente, mentre i dati effettivi risiedono in una tabella interna separata. Il metametodo __index recupera i valori dalla tabella dei dati e __newindex intercetta (e blocca) qualsiasi tentativo di scrittura!

Provalo tu

-- Importa il modulo ImmutableConfig
local ImmutableConfig = require('ImmutableConfig')

-- Leggi gli input
local appName = io.read()
local version = io.read()
local maxUsers = tonumber(io.read())

-- TODO: Crea un oggetto di configurazione usando ImmutableConfig.new()

-- TODO: Stampa tutti e tre i valori originali nel formato:
-- App: {appName}
-- Versione: {version}
-- Utenti massimi: {maxUsers}

-- TODO: Prova a modificare il campo maxUsers (questo dovrebbe generare un messaggio di errore)

-- TODO: Stampa di nuovo maxUsers per dimostrare che non è stato modificato
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Lua online