Lua è un lin­guag­gio di scripting svi­lup­pa­to in Brasile all’inizio degli anni ‘90. Il codice sorgente di un programma Lua viene tradotto in byte code ed eseguito dall’in­ter­pre­te Lua. L’in­ter­pre­te stesso è scritto in C, il che aiuta i programmi Lua a ottenere pre­sta­zio­ni elevate. Inoltre, l’API C consente al codice Lua di essere in­cor­po­ra­to in programmi C/C++. Lua è un lin­guag­gio mul­ti­pa­ra­dig­ma adatto a scrivere codice im­pe­ra­ti­vo, fun­zio­na­le e orientato agli oggetti.

Il prin­ci­pa­le punto di forza di Lua è la facile in­te­gra­zio­ne in altri sistemi e linguaggi. Lua si è così affermato come “glue language” ed è uti­liz­za­to in molti motori grafici di vi­deo­gio­chi. Il lin­guag­gio può essere uti­liz­za­to anche per con­trol­la­re server web come Apache e nginx. Lua viene spesso usato come lin­guag­gio di pro­gram­ma­zio­ne Internet autonomo tramite l’in­ter­fac­cia CGI. Inoltre, questo lin­guag­gio viene uti­liz­za­to anche per la pro­gram­ma­zio­ne di app mobili.

Tutorial sul lin­guag­gio di scripting Lua: i primi passi

Il modo più semplice e veloce per imparare a pro­gram­ma­re con Lua è eseguire il codice sulla pagina demo Lua in­te­rat­ti­va. Sarà possibile testare lì tutti gli esempi di codice Lua pre­sen­ta­ti più avanti in questo articolo. Basterà copiare uno degli esempi di codice nel campo di testo e fare clic su “run” per eseguire il codice.

In questo modo non dovete fare subito l’in­stal­la­zio­ne. Se de­si­de­ra­te uti­liz­za­re Lua sul vostro sistema, seguite le nostre istru­zio­ni. Al­tri­men­ti, andate di­ret­ta­men­te alla sezione “Imparare le basi del lin­guag­gio di scripting Lua”.

Preparare il proprio sistema per il tutorial su Lua

L’in­ter­pre­te Lua consiste in un singolo file binario di­spo­ni­bi­le sulla riga di comando dopo aver dato il comando “lua”. Questo viene me­mo­riz­za­to nel sistema e potrebbe dover essere incluso nel percorso. Lua offre anche librerie che con­sen­to­no l’in­cor­po­ra­men­to del codice nei programmi C/C++.

Per Mac e Linux, l’ideale è l’in­stal­la­zio­ne con il gestore di pacchetti “Homebrew”. Se avete in­stal­la­to Homebrew sul vostro sistema, è meglio se uti­liz­za­te il seguente codice sulla riga di comando per in­stal­la­re Lua:

brew install lua

Per in­stal­la­re Lua su un sistema Windows potete uti­liz­za­re LuaDist Installer.

Uti­liz­za­re l’in­ter­pre­te Lua in modo in­te­rat­ti­vo

Come spesso accade con i linguaggi di scripting, è possibile eseguire l’in­ter­pre­te Lua in modo in­te­rat­ti­vo. In modalità in­te­rat­ti­va, l’in­ter­pre­te riceve il codice Lua sulla riga di comando e lo esegue riga per riga. I valori generati vengono vi­sua­liz­za­ti di­ret­ta­men­te sulla riga di comando. Come utente, è possibile dunque con­trol­la­re e mo­di­fi­ca­re i valori delle variabili. Questo approccio è quindi par­ti­co­lar­men­te adatto per la pro­to­ti­pa­zio­ne rapida. Per avviare l’in­ter­pre­te Lua in modalità in­te­rat­ti­va, bisogna eseguire il seguente comando sulla riga di comando:

# Avviare l’interprete Lua in modalità interattiva
lua -i
N.B.

Per uscire di nuovo dalla modalità in­te­rat­ti­va, immettete il comando “os.exit ()” o premete i tasti [Ctrl] + [D] con­tem­po­ra­nea­men­te.

Eseguire lo script Lua per il tutorial con l’in­ter­pre­te

Invece di inserire il codice Lua pezzo per pezzo sulla riga di comando, potete istruire l’in­ter­pre­te Lua a eseguire un file di codice sorgente Lua completo. Per fare ciò, bisogna prima di tutto creare un file Lua e passare il nome del file all’in­ter­pre­te per l’ese­cu­zio­ne. L’in­ter­pre­te legge riga per riga il codice sorgente contenuto nel file e lo esegue.

# Eseguire lo script Lua
lua <nomefile> .lua
N.B.

I file di codice sorgente Lua terminano con l’esten­sio­ne “.lua”.

Rendere lo script Lua per il tutorial di­ret­ta­men­te ese­gui­bi­le usando uno shebang

Sui sistemi operativi Linux / UNIX / macOS, abbiamo anche la pos­si­bi­li­tà di rendere di­ret­ta­men­te ese­gui­bi­le un file di codice sorgente Lua. Per fare ciò, dobbiamo inserire un co­sid­det­to “shebang” come prima riga del file Lua:

#!/usr/local/bin/lua
--  Codice Lua per l’esecuzione

Os­ser­via­mo come lo shebang contenga la posizione del file binario Lua, nel nostro caso “#!/usr/local/bin/lua”. La posizione di ar­chi­via­zio­ne sul sistema locale potrebbe essere diversa. In questo caso, potete de­ter­mi­na­re la posizione del file binario Lua. A tale scopo, uti­liz­za­te il comando “which” sulla riga di comando:

# Determinare la posizione del file binario Lua
which lua

Dopo aver eseguito lo shebang di uno script Lua, dovete con­tras­se­gna­re il file come ese­gui­bi­le dall’utente. Quindi uti­liz­za­te il seguente codice sulla riga di comando:

# Contrassegnare il file Lua come eseguibile
chmod u + rx <nomefile> .lua

Suc­ces­si­va­men­te eseguite lo script Lua nella directory corrente:

./<nomefile>.lua
Consiglio

Il trucco shebang funziona su sistemi Linux e UNIX come macOS con la maggior parte dei linguaggi di scripting. Potete rendere gli script Ruby o Python di­ret­ta­men­te ese­gui­bi­li secondo lo stesso schema.

Imparare le basi del lin­guag­gio di scripting Lua

Lua è un lin­guag­gio mul­ti­pa­ra­dig­ma; lo stile di base è im­pe­ra­ti­vo e fun­zio­na­le. Il lin­guag­gio è com­ple­ta­men­te dinamico, ovvero non viene fatta alcuna di­stin­zio­ne tra “compile time” e “runtime”. Lua si affida alla gestione dinamica della memoria, senza eccezioni: la di­men­sio­ne di un oggetto in memoria può cambiare durante il runtime. Un “Garbage Collector” (GC) libera lo spazio in memoria che non è più ne­ces­sa­rio in modo che il pro­gram­ma­to­re non debba pre­oc­cu­par­se­ne.

Imparare a usare i commenti negli script Lua

I commenti sono una parte es­sen­zia­le di qualsiasi lin­guag­gio di pro­gram­ma­zio­ne. Fra gli altri, sono uti­liz­za­ti per i seguenti scopi:

  • Fare bozze delle com­po­nen­ti del codice
  • Do­cu­men­ta­re le ca­rat­te­ri­sti­che del codice
  • Attivare / di­sat­ti­va­re le righe di codice

Un commento a riga singola in Lua inizia con un doppio trattino (--) e arriva alla fine della riga:

-- Questa riga viene ignorata dall’interprete

In com­bi­na­zio­ne con le doppie parentesi quadre “[[“ e “]]” è possibile scrivere anche commenti su più righe:

--[[
Questo commento
si estende su
più righe.
]]

Valori e tipi per il tutorial del lin­guag­gio di scripting Lua

Come la maggior parte degli altri linguaggi di scripting, Lua è un lin­guag­gio tipizzato di­na­mi­ca­men­te. I tipi non ap­par­ten­go­no a variabili, ma a valori. Ogni valore ha un tipo specifico, sia esso un numero, una stringa di caratteri, un valore logico, ecc. Nel complesso, Lua ha una quantità gestibile di tipi, che sono riassunti qui di seguito:

Tipo Spie­ga­zio­ne
number numero decimale
string stringa
boolean valore di verità: “true” o “false”
nil valore mancante; il tipo ha solo il valore di “nil”
function funzione
table tipo di dato composto: lista / array, hash / dic­tio­na­ry
thread co-routine
userdata tipo di dati C definito dall’utente

Lua conosce la sintassi letterale per i valori di tutti i tipi ad eccezione di “thread” e “userdata”. Per de­ter­mi­na­re il tipo di un valore, usiamo la funzione “type ()”. Ciò re­sti­tui­sce il nome del tipo come stringa. Di seguito alcuni esempi:

type(42) -- il tipo è `number`
type("Lua Tutorial") -- il tipo è `string`
type(false) -- il tipo è `boolean`
type(var) -- il tipo è `nil` perché `var` non è definito

Imparare a pro­gram­ma­re con Lua: cosa sono espres­sio­ni, variabili e operatori?

Un’espres­sio­ne (“ex­pres­sion”) viene valutata dall’in­ter­pre­te e re­sti­tui­sce un valore. Le espres­sio­ni combinano letterali, operatori, variabili e chiamate di funzione. Le espres­sio­ni possono essere fa­col­ta­ti­va­men­te rag­grup­pa­te fra parentesi “()”. Essendo un lin­guag­gio dinamico, Lua determina au­to­ma­ti­ca­men­te il tipo di valore re­sti­tui­to. Di seguito alcuni esempi di espres­sio­ni:

-- Operazioni aritmetiche in Lua
1 + 2 -- valutato al valore “3”
-- Concatenazione di stringhe in Lua
'Walther' .. 'White' – restituito come 'WaltherWhite'
-- Concatenazione di stringhe con conversione automatica di un numero in Lua
'I ' .. 3 .. ' moschettieri' -- restituito come 'I 3 moschettieri'
-- Test di uguaglianza in Lua
7 == '7' -- restituisce `false`
-- Test di uguaglianza in Lua
'piccolo' == string.lower ('PICCOLO') -- restituisce `true`
-- Informazioni di tipo dinamico
type (var) == 'nil'-- restituisce `true` perché `var` non è definito

Una variabile è un nome per un valore in memoria. Come nella maggior parte dei linguaggi di pro­gram­ma­zio­ne, un nome in Lua inizia con una lettera o un trattino basso (_), seguito da lettere ag­giun­ti­ve, trattini bassi o numeri. Viene fatta una netta di­stin­zio­ne tra maiuscole e minuscole. Le seguenti parole riservate non possono essere uti­liz­za­te come nomi da sole:

“And”, “end”, “in”, “repeat”, “break”, “false”, “local”, “return”, “do”, “for”, “nil”, “then”, “else”, “function”, “not”, “true”, “elseif”, “if”, “or”, “until”, “while”

Tuttavia, queste parole riservate possono apparire come parte di un nome senza problemi:

for = "Peter" -- causa errori
for_user = "Peter" -- consentito

Un valore viene assegnato a una variabile uti­liz­zan­do l’operatore di as­se­gna­zio­ne (=), che non deve essere confuso con l’operatore di ugua­glian­za logica (==). Come al solito, durante l’as­se­gna­zio­ne viene fatta una di­stin­zio­ne tra “L-value” e “R-value”: la variabile deve essere a sinistra dell’operatore di as­se­gna­zio­ne, cioè è il valore L. A questo viene assegnato il valore valutato del valore R a destra:

numero = 13 -- va bene
13 = numero -- causa errori perché al numero 13 non può essere assegnato un nuovo valore

Un operatore crea un nuovo valore da uno o più operandi. Si parla di un operatore unario (una cifra) o binario (due cifre). Un operatore collega operandi di un certo tipo e re­sti­tui­sce un valore di un certo tipo. Diamo un’occhiata ai diversi operatori in Lua.

Gli operatori arit­me­ti­ci operano sui numeri e re­sti­tui­sco­no un numero:

Operatore arit­me­ti­co Arietà Ope­ra­zio­ne
+ binario addizione
- binario sot­tra­zio­ne
* binario mol­ti­pli­ca­zio­ne
/ binario divisione
% binario modulo
^ binario ele­va­zio­ne a potenza
- unario negazione

Gli operatori re­la­zio­na­li sono tutti binari e testano la relazione tra due operandi. Re­sti­tui­sco­no un valore di verità:

Operatore re­la­zio­na­le Test
== ugua­glian­za
~= di­su­gua­glian­za
> maggiore di
< minore di
>= maggiore o uguale a
<= minore o uguale a

Gli operatori logici combinano valori di verità e re­sti­tui­sco­no un nuovo valore di verità:

Operatore logico Arietà Ope­ra­zio­ne
and binario col­le­ga­men­to E
or binario col­le­ga­men­to O
not unario negazione

Oltre a quanto riportato sopra, ci sono due operatori speciali in Lua che servono per con­ca­te­na­re stringhe e de­ter­mi­na­re la potenza di un valore composto, come una tabella o una stringa:

Operatore Arietà Ope­ra­zio­ne
.. binario con­ca­te­na­zio­ne di stringhe
# unario de­ter­mi­na­re il numero di elementi di una tabella / la lunghezza di una stringa

Lua non ha operatori di as­se­gna­zio­ne composti come “+=“ e “-=“, che sono comuni in molti linguaggi di scripting. Per aumentare e diminuire le variabili, l’ope­ra­zio­ne viene scritta espli­ci­ta­men­te:

prezzo = 42.99
sconto = 0.15 -- 15% di sconto
prezzo -= prezzo * sconto -- `-=` non funziona in Lua
-- La diminuzione deve essere invece scritta esplicitamente
prezzo = prezzo - (prezzo * sconto)

Com­pren­de­re gli ambiti di validità e i blocchi per il tutorial di Lua

Il concetto di “ambito di validità” è centrale in qualsiasi lin­guag­gio di pro­gram­ma­zio­ne. Una variabile esiste solo entro un certo ambito di validità. Come in Ja­va­Script, le variabili in Lua sono globali per im­po­sta­zio­ne pre­de­fi­ni­ta. Tuttavia, l’uso continuo di variabili globali è noto come “anti-pattern” e dovrebbe essere evitato. In Lua, la parola chiave “local” può essere d’aiuto. Infatti, limita l’ambito di una variabile al blocco cir­co­stan­te, pa­ra­go­na­bi­le alla di­chia­ra­zio­ne tramite “let” in Ja­va­Script.

-- questa variabile è globale
x = 5
-- definire variabile locale
local z = 10

I corpi delle funzioni e i cicli aprono un nuovo ambito di validità in Lua. Lua utilizza anche il concetto di blocco esplicito. Un blocco definisce un nuovo ambito di validità per il codice che si trova fra le parole chiave “do” e “end”. Ciò cor­ri­spon­de alle parentesi di apertura e chiusura “{“ e ”}” in Java/C/C++. Il seguente esempio di codice mostra come sono correlati blocchi, ambiti e variabili:

-- ambito di validità esterno
do
    local x = 1
    do -- ambito di validità interno
        local y = 2
        -- generare `z` nell’ambito globale
        -- accedere così alla variabile locale `x` da un ambito di validità esterno
        -- così come alla variabile locale `y` dall’ambito di validità interno
        z = x + y -- `z` ora ha il valore `3`
    end
    print(x) -- restituisce `1`
    print (y) – restituisce `nil` poiché `y` non esiste nell’ambito di validità esterno
    print(z) -- restituisce `3` 
end
-- `z` è globale, quindi esiste al di fuori dell’ambito di validità esterno
z = z + 4
print(z) -- restituisce `7`

Imparare a pro­gram­ma­re con le strutture di controllo di Lua

Lua utilizza le classiche strutture di controllo che troviamo anche in altri linguaggi di pro­gram­ma­zio­ne. Ciò include di­ra­ma­zio­ni e cicli. Di seguito un esempio delle direttive “if”, “then”, “else”, “elseif” di Lua:

limit = 42;
numero = 43;
se numero < limit then
    print("sotto il limite.")
elseif numero == limit then
    print("esattamente al limite…")
else
    print("oltre il limite!")
end

Oltre al classico ciclo “while”, Lua riconosce anche la sua con­tro­par­te “repeat”-”until”. Questa istru­zio­ne esiste anche in Ruby e richiede l’in­ver­sio­ne della con­di­zio­ne applicata. Ciò significa che “while” con la con­di­zio­ne “numero </= limit” cor­ri­spon­de a “repeat”-”until” con la con­di­zio­ne “numero > limit”. At­ten­zio­ne all’istru­zio­ne “repeat”! In­di­pen­den­te­men­te dalla con­di­zio­ne, il ciclo viene eseguito almeno una volta. Qui un esempio:

limit = 10
numero = 1
while numero <= limit do
    print("Numero:", numero)
    numero = numero + 1
end
-- Attenzione: anche se il `numero` è già maggiore del `limite`
-- il ciclo viene eseguito una volta
numero = 11
repeat 
    print("Numero:", numero)
    numero = numero + 1
until numero > limit

Come la maggior parte dei linguaggi di pro­gram­ma­zio­ne im­pe­ra­ti­vi, Lua ha anche un’istru­zio­ne “for” oltre al ciclo “while”. Possono essere uti­liz­za­te due forme: una variante simile a C con una variabile di ciclo e una variante con un iteratore. Con­si­de­ria­mo prima l’uso dell’istru­zio­ne “for” con una variabile di ciclo:

inizio = 1
fine = 10
for numero = inizio, fine do
    print("numero corrente:", numero) -- `1,2,3,4,5,6,7,8,9,10`
end
-- impostare esplicitamente il passaggio a `2`
passaggio = 2
for numero = inizio, fine, passaggio do
    print("numero corrente:", numero) -- `1,3,5,7,9`
end
-- il passaggio può anche essere negativo
passaggio = -2
-- scambiare l’inizio e la fine con un passaggio negativo per contare in ordine decrescente
for numero = fine, inizio, passaggio do
    print("numero corrente:", numero) -- `10,8,6,4,2`
end

Al contrario di quello che si potrebbe pensare, la variabile definita nel ciclo “for” è locale, non globale, senza dover essere espli­ci­ta­men­te di­chia­ra­ta come “locale” ed è qui che Lua dif­fe­ri­sce da Ja­va­Script in modo positivo. In Ja­va­Script, una variabile di ciclo senza “let” o “var” viene di­chia­ra­ta au­to­ma­ti­ca­men­te come globale, il che può portare a gravi errori.

Diamo adesso un’occhiata al ciclo “for” di Lua con l’iteratore. In linea di principio, l’approccio è simile a quello di Python: invece di in­cre­men­ta­re una variabile di ciclo e usarla come indice in una lista, iteriamo di­ret­ta­men­te sugli elementi della lista. La funzione “ipairs()” viene spesso uti­liz­za­ta per generare l’iteratore. Ecco un esempio:

-- definire una lista di anni
decadi = {1910, 1920, 1930, 1940, 1950, 1960, 1970, 1980, 1990}
-- accedere ai singoli anni utilizzando un iteratore
for index, anni in ipairs(decadi) do
    print(index, anno)
end

Ulteriori in­for­ma­zio­ni sulle funzioni di Lua

Come in C/C++, Java e Ja­va­Script, le funzioni sono definite con la parola chiave “function”. Come spesso accade, i parametri delle funzioni seguono i nomi delle funzioni tra parentesi. La par­ti­co­la­ri­tà di Lua è che le parentesi possono essere omesse quando si richiama una funzione che ha esat­ta­men­te un letterale come argomento. Una funzione di Lua non deve ne­ces­sa­ria­men­te re­sti­tui­re un valore. Secondo la de­fi­ni­zio­ne, in assenza di un valore si tratta di una “procedura”:

-- definire procedura
function ciao(name)
    print("buongiorno", name)
end
-- richiamare una funzione
ciao("Gentile Signore")
-- è possibile anche
ciao "Gentile Signore"
-- l’opzione seguente invece non funziona
name = "Walther"
ciao name -- errore di sintassi
-- la funzione deve essere richiamata fra parentesi con una variabile invece di un letterale
ciao(name)

Se si vuole re­sti­tui­re un valore da una funzione, come al solito si può uti­liz­za­re la parola chiave “return”. Ciò termina l’ese­cu­zio­ne della funzione e re­sti­tui­sce il valore spe­ci­fi­ca­to. Nel seguente esempio di codice un numero viene mol­ti­pli­ca­to al quadrato:

-- funzione con un unico valore di ritorno
function quadrato(numero)
    -- viene valutata l’espressione `numero * numero`
    -- e il suo valore restituito
    return numero * numero
end
-- numero al quadrato
print(quadrato(9)) -- `81`

Come in Python e Ja­va­Script, una funzione in Lua può accettare un numero variabile di argomenti. Gli argomenti vengono salvati nel costrutto speciale “(...)”. Per accedere agli argomenti, è spesso utile rias­su­mer­li in una lista con l’espres­sio­ne “{...}”. In al­ter­na­ti­va, può essere uti­liz­za­ta la funzione “select ()”, che estrae un argomento sotto l’indice spe­ci­fi­ca­to. Il numero di argomenti viene de­ter­mi­na­to con l’espres­sio­ne “# {...}”.

-- stampare tutti gli argomenti di una funzione
function var_args(...)
    for index, arg    in ipairs({...}) do
        print(index, arg)
    end
end
var_args('Peter', 42, true)

Oltre al numero variabile di argomenti, Lua consente anche di re­sti­tui­re più valori con l’istru­zio­ne “return”. Funziona in modo simile a Python, ma senza un tipo “tupla” esplicito. Come in Python, è comune assegnare i valori di ritorno a più variabili quando si chiama una funzione. Ecco un esempio:

-- funzione con diversi valori di ritorno
function primo_e_ ultimo(lista)
    -- restituisce il primo e l’ultimo elemento della lista
    -- i singoli valori di ritorno sono separati da una virgola `,`
    return lista[1], lista[#lista]
end
persone = {"Jim", "Jack", "John"}
-- assegnazione dei valori di ritorno a più variabili
primo, ultimo = primo_e_ultimo(persone)
print("Il primo è", primo)
print("L’ultimo è", ultimo)

Se uno dei valori re­sti­tui­ti non è ne­ces­sa­rio, la con­ven­zio­ne comune consiste nell’uti­liz­za­re il trattino basso (_) come se­gna­po­sto, come mostrato nell’esempio seguente:

function min_medio_max(...)
    -- impostare i valori iniziali per `min` e `max` al primo argomento
    local min = select(1, ...)
    local max = select(1, ...)
    -- impostare inizialmente a zero il valore medio
    local medio = 0
    -- ripetere i numeri
    -- non abbiamo bisogno della variabile index
    -- utilizzare quindi `_` come segnaposto
    for _, numero in ipairs({...}) do
        -- impostare un nuovo minimo
        if min > numero then
            min = numero
        end
        -- impostare un nuovo massimo
        if max < numero then
            max = numero
        end
        -- sommare i numeri per la media
        medio = medio + numero
    end
    -- dividere la somma dei numeri per il loro numero
    medio = medio / #{...}
    return min, medio, max
end
-- qui non abbiamo bisogno del valore `medio`
-- utilizziamo quindi `_` come segnaposto
min, _, max = min_medio_max(78, 34, 91, 7, 28)
print("il minimo e il massimo dei numeri sono", min, max)

In Lua, le funzioni sono “first-class citizens”. Ciò significa che possono essere associate a variabili e quindi trasmesse anche come argomenti ad altre funzioni. Una funzione può inoltre servire come valore di ritorno di una funzione. Lua consente una pro­gram­ma­zio­ne fun­zio­na­le, mostrata qui usando l’esempio della famosa funzione “map ()”:

-- `map()`-funzione di Lua
-- accetta una funzione `f` e una lista come argomenti
function map(f, lista)
    --creare una nuova lista per i valori di output
    local _lista = {}
    -- scorrere gli elementi della lista con indice
    for index, valore in ipairs(lista) do
        -- applicare la funzione `f()` al valore corrente della lista
        -- e salvare il valore restituito in una nuova lista con lo stesso indice
        _lista[index] = f(valore)
    end
    -- restituire una nuova lista
    return _lista
end
-- lista di numeri
numeri = {3, 4, 5}
-- funzione che viene applicata a tutti gli elementi della lista
function quadrato(numero)
    return numero * numero
end
-- generare i quadrati tramite la funzione `map()`
quadrati = map(quadrato, numeri) -- `{9, 16, 25}`
-- restituire i numeri al quadrato
for _, numero in ipairs(quadrati) do
    print(numero)
end

La ri­cor­si­vi­tà viene spesso uti­liz­za­ta nella pro­gram­ma­zio­ne fun­zio­na­le: una funzione chiama se stessa più e più volte con argomenti mo­di­fi­ca­ti. Bisogna fare par­ti­co­la­re at­ten­zio­ne con Lua. Le funzioni ri­chia­ma­te in modo ricorsivo do­vreb­be­ro essere di­chia­ra­te espli­ci­ta­men­te come “local”.

function f()
    -- chiamata ricorsiva
    f () -- si riferisce alla variabile globale `f`, se applicabile
end
-- anziché
local function f()
    -- chiamata ricorsiva
    f () -- si riferisce alla funzione circostante
end
-- equivalente a
local f; -- dichiarare la variabile `f` esplicitamente come `local` 
f = function () -- assegnazione della funzione alla variabile locale `f`
    f () -- si riferisce di sicuro alla funzione circostante
end
Vai al menu prin­ci­pa­le