Menu
Coddy logo textTech

Collegare con __index

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

Hai una tabella prototipo con proprietà e metodi, ma come fai a far sì che un nuovo oggetto la utilizzi davvero? La risposta è nel metametodo __index.

Quando accedi a una chiave che non esiste in una tabella, Lua normalmente restituisce nil. Tuttavia, se la tabella ha una metatabella con un campo __index, Lua cercherà lì. Impostando __index in modo che punti al tuo prototipo, le chiavi mancanti vengono trovate automaticamente nel prototipo:

local Dog = {
    species = "Canis familiaris",
    legs = 4
}

function Dog:bark()
    print("Woof!")
end

-- Crea un'istanza vuota
local myDog = {}

-- Collegala al prototipo
setmetatable(myDog, { __index = Dog })

print(myDog.species)  -- Output: Canis familiaris
myDog:bark()          -- Output: Woof!

La tabella myDog è completamente vuota, eppure accedere a myDog.species funziona. Quando Lua non trova species in myDog, controlla __index della metatabella e lo trova in Dog.

Questa è la base della programmazione orientata agli oggetti in Lua. L'istanza può avere i propri dati univoci, mentre il comportamento condiviso risiede nel prototipo. Nella prossima lezione imparerai a racchiudere questo schema in una funzione costruttrice pulita.

challenge icon

Sfida

Facile

Ora mettiamo in pratica il metametodo __index! Creerai un prototipo e vi collegherai un'istanza, consentendo all'istanza di accedere a proprietà e metodi che non possiede direttamente.

Organizzerai il codice in due file:

  • Robot.lua: definisci una tabella prototipo Robot con:
    • Un campo model impostato su "RX-100"
    • Un campo batteryLevel impostato su 100
    • Un metodo :status() che stampa lo stato attuale del robot
    Restituisci la tabella alla fine del file.
  • main.lua: richiedi il modulo Robot, quindi crea una tabella di istanza vuota e collegala al prototipo Robot usando setmetatable con __index. Questo consente alla tua istanza vuota di accedere a tutto ciò che proviene dal prototipo.

Riceverai un input: un nome da assegnare all'istanza del tuo robot.

Dopo aver collegato l'istanza al prototipo:

  1. Assegna il nome dell'input al campo name della tua istanza (che diventa unico per l'istanza)
  2. Chiama il metodo :status() sulla tua istanza

Il tuo metodo :status() dovrebbe stampare esattamente nel seguente formato:

[name] ([model]) - Battery: [batteryLevel]%

Per esempio, se l'input è Sparky, l'output dovrebbe essere:

Sparky (RX-100) - Battery: 100%

Nota che l'istanza ha il proprio name, ma accede a model e batteryLevel dal prototipo tramite il collegamento __index.

Provalo tu

-- Leggi l'input
local name = io.read()

-- Carica il modulo Robot con require
local Robot = require('Robot')

-- TODO: Crea una tabella vuota per l'istanza

-- TODO: Collega l'istanza al prototipo Robot usando setmetatable con __index

-- TODO: Assegna il nome ricevuto in input al campo name della tua istanza

-- TODO: Chiama il metodo :status() sulla tua istanza
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