Menu
Coddy logo textTech

Il metametodo __newindex

Fa parte della sezione Logica e flusso del percorso Lua di Coddy. Lezione 19 di 54.

Hai imparato come __index controlla cosa succede quando provi a leggere una chiave che non esiste in una tabella. Ora scoprirai la sua controparte: __newindex, che controlla cosa succede quando provi ad aggiungere o modificare una coppia chiave-valore.

Il metametodo __newindex viene attivato ogni volta che provi ad assegnare un valore a una chiave che al momento non esiste nella tabella. Questo ti permette di intercettare e controllare le modifiche prima che avvengano.

Ecco un semplice esempio che impedisce di aggiungere nuove chiavi a una tabella:

local readOnly = {}
local meta = {
    __newindex = function(table, key, value)
        print("Cannot add key: " .. key)
    end
}

setmetatable(readOnly, meta)

readOnly.name = "Alice"  -- Output: Cannot add key: name
print(readOnly.name)     -- Output: nil

Quando provi a impostare readOnly.name = "Alice", Lua vede che name non esiste nella tabella. Invece di aggiungerlo, Lua chiama la funzione __newindex con tre argomenti: la tabella stessa, la chiave da impostare e il valore assegnato.

In questo esempio, la funzione si limita a stampare un messaggio e in realtà non memorizza nulla.

Puoi anche usare __newindex per convalidare i dati prima di consentirne l'inserimento nella tua tabella:

local player = {}
local meta = {
    __newindex = function(t, key, value)
        if key == "health" and type(value) ~= "number" then
            print("Health must be a number!")
        else
            rawset(t, key, value)
        end
    end
}

setmetatable(player, meta)

player.health = "high"  -- Output: Health must be a number!
player.health = 100     -- Consentito

Nota l’uso di rawset() nel secondo esempio. Questa funzione ignora la metatabella e imposta direttamente il valore nella tabella.

Senza di esso, impostare il valore attiverebbe di nuovo __newindex, creando un ciclo infinito.

challenge icon

Sfida

Facile
Scrivi una funzione createValidatedTable che accetta key e value e restituisce una tabella che accetta solo valori stringa per le nuove chiavi.

Crea una tabella vuota e associa una metatabella con __newindex che convalida il tipo del valore. Se qualcuno prova ad aggiungere un valore che non è una stringa, usa rawset() per memorizzare la stringa "invalid" al suo posto. Per i valori stringa, memorizzali normalmente usando rawset().

Logica:

  • Crea una tabella vuota
  • Crea una metatabella con __newindex che riceve la tabella, la chiave e il valore
  • All'interno di __newindex, controlla se il valore è una stringa usando type(value) == "string"
  • Se è una stringa, usa rawset(t, key, value) per memorizzarla
  • Se non è una stringa, usa rawset(t, key, "invalid") per memorizzare "invalid" al suo posto
  • Associa la metatabella alla tabella usando setmetatable()
  • Usa rawset() per aggiungere alla tabella la coppia chiave-valore iniziale (ignorando la metatabella)
  • Restituisci la tabella

Parametri:

  • key (stringa): la chiave iniziale da aggiungere alla tabella
  • value (stringa): il valore iniziale da aggiungere alla tabella

Restituisce: una tabella con convalida che accetta solo valori stringa e contiene la coppia chiave-valore iniziale (tabella)

Provalo tu

function createValidatedTable(key, value)
    -- Scrivi il codice qui
end
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 Logica e flusso

Esercitati da solo: Compilatore Lua online