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: nilQuando 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 -- ConsentitoNota 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.
Sfida
FacileScrivi 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
__newindexche riceve la tabella, la chiave e il valore - All'interno di
__newindex, controlla se il valore è una stringa usandotype(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 tabellavalue(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
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Logica e flusso
1Iterazione avanzata delle tabelle
Iterare con pairs()Iterare con ipairs()pairs() vs. ipairs()Riepilogo - Scheda del personaggio4Introduzione alle metatabelle
Che cos’è una metatabella?setmetatable e getmetatableIl metametodo __indexIl metametodo __newindexIl metametodo __tostringMetametodi aritmetici - Parte 1Metametodi aritmetici - Parte 2Riepilogo - Tabella di sola lettura2Altre funzioni della libreria table
table.concat()Costruzione di tabelle e unpack()table.sort()Ordinamento personalizzato con funzioniRiepilogo - Tabellone dei punteggi più altiEsercitati da solo: Compilatore Lua online