Menu
Coddy logo textTech

Accesso tramite closure

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

Le variabili locali private sono inutili se non puoi mai interagire con esse. La soluzione è definire metodi getter e setter all'interno del costruttore, dove hanno accesso all'ambito della chiusura.

Poiché questi metodi vengono creati all'interno di :new(), possono "vedere" le variabili locali. Li assegni direttamente all'oggetto:

local Counter = {}
Counter.__index = Counter

function Counter:new()
    local count = 0  -- Variabile privata
    
    local obj = {}
    
    -- Definisci i metodi all'interno del costruttore
    function obj:getCount()
        return count
    end
    
    function obj:increment()
        count = count + 1
    end
    
    setmetatable(obj, Counter)
    return obj
end

Ora è possibile accedere alla variabile privata count, ma solo tramite i metodi che fornisci:

local c = Counter:new()
print(c:getCount())  -- 0
c:increment()
c:increment()
print(c:getCount())  -- 2
print(c.count)       -- nil (¡sigue oculto!)

Nota che :getCount() e :increment() sono definite direttamente su obj, non sulla tabella della classe. Ogni istanza ottiene una propria copia di queste funzioni, ciascuna con accesso al proprio count privato. Questo è il compromesso: la vera privacy costa un po' più di memoria, poiché i metodi non sono condivisi tramite il prototipo.

challenge icon

Sfida

Facile

Creiamo una classe Temperature che usa la privacy basata sulle closure per memorizzare un valore di temperatura in gradi Celsius, con metodi getter e setter definiti all'interno del costruttore per fornire un accesso controllato!

Organizzerai il codice in due file:

  • Temperature.lua: crea una classe in cui il valore della temperatura è memorizzato in una variabile locale all'interno del costruttore: completamente nascosta dall'accesso esterno. Il costruttore :new(initialCelsius) dovrebbe memorizzare la temperatura in una variabile locale, quindi definire questi metodi direttamente sull'istanza dell'oggetto:
    • :getCelsius(): restituisce la temperatura attuale in gradi Celsius
    • :setCelsius(value): aggiorna la temperatura con un nuovo valore
    • :getFahrenheit(): restituisce la temperatura convertita in Fahrenheit usando la formula: (celsius * 9/5) + 32
  • main.lua: importa il modulo Temperature e legge due valori dall'input: una temperatura iniziale e una nuova temperatura da impostare. Crea un'istanza di Temperature con il valore iniziale, stampa le letture in Celsius e Fahrenheit, poi usa il setter per modificare la temperatura e stampa di nuovo entrambe le letture.

Riceverai due input:

  1. La temperatura iniziale in gradi Celsius (un numero)
  2. Una nuova temperatura da impostare (un numero)

L'output dovrebbe essere composto da quattro righe che mostrano le letture della temperatura prima e dopo la modifica:

Celsius: {initialValue}
Fahrenheit: {convertedInitial}
Celsius: {newValue}
Fahrenheit: {convertedNew}

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

Celsius: 0
Fahrenheit: 32
Celsius: 100
Fahrenheit: 212

Ricorda: il valore della temperatura deve essere memorizzato in una variabile locale all'interno di :new(), non su self. I metodi getter e setter sono definiti all'interno del costruttore, dove possono accedere a questa variabile privata tramite una closure. Tentare di accedere direttamente a temp.celsius o temp._celsius dovrebbe restituire nil!

Provalo tu

-- Carica il modulo Temperature
local Temperature = require('Temperature')

-- Leggi i valori di input
local initialTemp = tonumber(io.read())
local newTemp = tonumber(io.read())

-- TODO: Crea un'istanza di Temperature con il valore iniziale

-- TODO: Stampa le letture iniziali in Celsius e Fahrenheit

-- TODO: Usa il setter per cambiare la temperatura in newTemp

-- TODO: Stampa le letture aggiornate in Celsius e Fahrenheit
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