2020-04-27 16:11:54 +03:00
---
2020-06-18 22:37:44 +03:00
title: Programmare in Lua
2020-04-27 16:11:54 +03:00
layout: default
root: ../..
idx: 1.2
2020-05-01 17:53:35 +03:00
description: Un'introduzione a Lua, con inclusa una guida alla portata globale/locale.
redirect_from: /it/chapters/lua.html
2020-04-27 16:11:54 +03:00
---
2020-05-01 17:53:35 +03:00
## Introduzione <!-- omit in toc -->
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
In questo capitolo parleremo della programmazione in Lua, degli strumenti necessari, e tratteremo alcune tecniche che troverai probabilmente utili.
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
- [Editor di codice ](#editor-di-codice )
- [Programmare in Lua ](#programmare-in-lua )
- [Flusso del programma ](#flusso-del-programma )
- [Tipi di variabili ](#tipi-di-variabili )
- [Operatori matematici ](#operatori-matematici )
- [Selezione ](#selezione )
- [Operatori logici ](#operatori-logici )
- [Programmare ](#programmare )
- [Portata locale e globale ](#portata-locale-e-globale )
- [Local dovrebbe essere usato il più possibile ](#local-dovrebbe-essere-usato-il-piu-possibile )
- [Inclusione di altri script Lua ](#inclusione-di-altri-script-lua )
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
## Editor di codice
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
Un editor di codice con evidenziamento delle parole chiave è sufficiente per scrivere script in Lua.
2020-08-20 01:49:39 +03:00
L'evidenziamento assegna colori diversi a parole e caratteri diversi a seconda del loro significato, permettendo di individuare più facilmente eventuali errori.
2020-04-27 16:11:54 +03:00
```lua
function ctf.post(team,msg)
if not ctf.team(team) then
return false
end
if not ctf.team(team).log then
ctf.team(team).log = {}
end
table.insert(ctf.team(team).log,1,msg)
ctf.save()
return true
end
```
2020-05-01 17:53:35 +03:00
Per esempio, parole chiave come if, then, end e return sono evidenziate nel passaggio qui sopra.
2020-08-20 01:49:39 +03:00
Lo stesso vale per le funzioni interne di Lua come table.insert.
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
Segue una lista di editor noti che si prestano bene per programmare in Lua.
Non sono, ovviamente, gli unici esisteneti.
2020-04-27 16:11:54 +03:00
* Windows: [Notepad++ ](http://notepad-plus-plus.org/ ), [Atom ](http://atom.io/ ), [VS Code ](https://code.visualstudio.com/ )
* Linux: Kate, Gedit, [Atom ](http://atom.io/ ), [VS Code ](https://code.visualstudio.com/ )
* OSX: [Atom ](http://atom.io/ ), [VS Code ](https://code.visualstudio.com/ )
2020-05-01 17:53:35 +03:00
## Programmare in Lua
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
### Flusso del programma
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
I programmi sono una serie di comandi che vengono eseguiti uno dopo l'altro.
Chiamiamo questi comandi "istruzioni".
2020-08-20 01:49:39 +03:00
Il flusso del programma è il come queste istruzioni vengono eseguite, e a differenti tipi di flusso corrispondono comportamenti diversi.
Essi possono essere:
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
* Sequenziali: eseguono un'istruzione dopo l'altra, senza salti.
* Selettivi: saltano alcune sequenze a seconda delle condizioni.
* Iteranti: ripetono ciclicamente. Continuano a eseguire le stesse istruzioni
2020-05-01 17:53:35 +03:00
finché una condizione non è soddisfatta.
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
Quindi, come vengono rappresentate le istruzioni in Lua?
2020-04-27 16:11:54 +03:00
```lua
2020-05-01 17:53:35 +03:00
local a = 2 -- Imposta 'a' a 2
local b = 2 -- Imposta 'b' a 2
local risultato = a + b -- Imposta 'risultato' ad a + b, cioè 4
2020-04-27 16:11:54 +03:00
a = a + 10
2020-05-01 17:53:35 +03:00
print("La somma è ".. risultato)
2020-04-27 16:11:54 +03:00
```
2020-05-01 17:53:35 +03:00
Whoa, cos'è appena successo?
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
a, b, e risultato sono *variabili* . Le variabili locali si dichiarano tramite l'uso della parola chiave local (che vedremo tra poco), e assegnando eventualmente loro un valore iniziale.
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
Il simbolo `=` significa *assegnazione* , quindi `risultato = a + b` significa impostare "risultato" ad a + b.
2020-08-20 01:49:39 +03:00
Per quanto riguarda i nomi delle variabili, essi possono essere più lunghi di un carattere - al contrario che in matematica - come visto in "risultato", e vale anche la pena notare che Lua è *case-sensitive* (differenzia maiuscole da minuscole);
2020-05-01 17:53:35 +03:00
A è una variabile diversa da a.
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
### Tipi di variabili
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
Una variabile può equivalere solo a uno dei seguenti tipi e può cambiare tipo dopo l'assegnazione.
2020-08-20 01:49:39 +03:00
È buona pratica assicurarsi che sia sempre solo o nil o diversa da nil.
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
| Tipo | Descrizione | Esempio |
2020-04-27 16:11:54 +03:00
|----------|---------------------------------|----------------|
2020-05-01 17:53:35 +03:00
| Nil | Non inizializzata. La variabile è vuota, non ha valore | `local A` , `D = nil` |
| Numero | Un numero intero o decimale | `local A = 4` |
| Stringa | Una porzione di testo | `local D = "one two three"` |
| Booleano | Vero o falso (true, false) | `local is_true = false` , `local E = (1 == 1)` |
| Tabella | Liste | Spiegate sotto |
| Funzione | Può essere eseguita. Può richiedere input e ritornare un valore | `local result = func(1, 2, 3)` |
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
### Operatori matematici
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
Lista non esaustiva, ce ne sono altri
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
| Simbolo | Scopo | Esempio |
|---------|--------------------|---------------------------|
| A + B | Addizione | 2 + 2 = 4 |
| A - B | Sottrazione | 2 - 10 = -8 |
| A * B | Moltiplicazione | 2 * 2 = 4 |
| A / B | Divisione | 100 / 50 = 2 |
| A ^ B | Potenze | 2 ^ 2 = 2< sup > 2< / sup > = 4 |
| A .. B | Concatena stringhe | "foo" .. "bar" = "foobar" |
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
### Selezione
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
La selezione più basica è il costrutto if.
Si presenta così:
2020-04-27 16:11:54 +03:00
```lua
2020-05-01 17:53:35 +03:00
local random_number = math.random(1, 100) -- Tra 1 e 100.
2020-04-27 16:11:54 +03:00
if random_number > 50 then
print("Woohoo!")
else
print("No!")
end
```
2020-08-20 01:49:39 +03:00
Questo esempio genera un numero casuale tra 1 e 100.
Stampa poi "Woohoo!" se il numero è superiore a 50, altrimenti stampa "No!".
Cos'altro si può usare oltre a '>'?
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
### Operatori logici
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
| Simbolo | Scopo | Esempio |
2020-04-27 16:11:54 +03:00
|---------|--------------------------------------|-------------------------------------------------------------|
2020-05-01 17:53:35 +03:00
| A == B | Uguale a | 1 == 1 (true), 1 == 2 (false) |
| A ~= B | Non uguale a (diverso da) | 1 ~= 1 (false), 1 ~= 2 (true) |
| A > B | Maggiore di | 5 > 2 (true), 1 > 2 (false), 1 > 1 (false) |
| A < B | Minore di | 1 < 3 ( true ) , 3 < 1 ( false ) , 1 < 1 ( false ) |
| A >= B | Maggiore o uguale a | 5 >= 5 (true), 5 >= 3 (true), 5 >= 6 (false) |
| A < = B | Minore o uguale a | 3 < = 6 (true), 3 < = 3 (true) |
| A and B | E (entrambi devono essere veri) | (2 > 1) and (1 == 1) (true), (2 > 3) and (1 == 1) (false) |
| A or B | O (almeno uno dei due vero) | (2 > 1) or (1 == 2) (true), (2 > 4) or (1 == 3) (false) |
| not A | non vero | not (1 == 2) (true), not (1 == 1) (false) |
2020-08-20 01:49:39 +03:00
La lista non è esaustiva, e gli operatori possono essere combinati, come da esempio:
2020-04-27 16:11:54 +03:00
```lua
if not A and B then
print("Yay!")
end
```
2020-05-01 17:53:35 +03:00
Che stampa "Yay!" se A è falso e B vero.
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
Gli operatori logici e matematici funzionano esattamente allo stesso modo; entrambi accettano input e ritornano un valore che può essere immagazzinato.
2020-04-27 16:11:54 +03:00
```lua
local A = 5
local is_equal = (A == 5)
if is_equal then
2020-05-01 17:53:35 +03:00
print("È equivalente!")
2020-04-27 16:11:54 +03:00
end
```
2020-05-01 17:53:35 +03:00
## Programmare
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
Programmare è l'azione di prendere un problema, come ordinare una lista di oggetti, e tramutarlo in dei passaggi che il computer può comprendere.
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
Insegnarti i processi logici della programmazione non rientra nell'ambito di questo libro; tuttavia, i seguenti siti sono alquanto utili per approfondire l'argomento:
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
* [Codecademy ](http://www.codecademy.com/ ) è una delle migliori risorse per imparare come scrivere codice; offre un'esperienza guidata interattiva.
* [Scratch ](https://scratch.mit.edu ) è una buona risorsa quando si comincia dalle basi assolute, imparando le tecniche di problem solving necessarie per la programmazione.\\
2020-05-01 17:53:35 +03:00
Scratch è **ideato per insegnare ai bambini** e non è un linguaggio serio di programmazione.
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
## Portata locale e globale
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
L'essere locale o globale di una variabile determina da dove è possibile accederci.
Una variabile locale è accessibile soltanto da dove viene definita. Ecco alcuni esempi:
2020-04-27 16:11:54 +03:00
```lua
2020-05-01 17:53:35 +03:00
-- Accessibile dall'interno dello script
2020-04-27 16:11:54 +03:00
local one = 1
function myfunc()
2020-05-01 17:53:35 +03:00
-- Accessibile dall'interno della funzione
2020-04-27 16:11:54 +03:00
local two = one + one
if two == one then
2020-05-01 17:53:35 +03:00
-- Accessible dall'interno del costrutto if
2020-04-27 16:11:54 +03:00
local three = one + two
end
end
```
2020-05-01 17:53:35 +03:00
Mentre le variabili globali sono accessibili da qualsiasi script di qualsiasi mod.
2020-04-27 16:11:54 +03:00
```lua
2020-05-01 17:53:35 +03:00
my_global_variable = "ciao"
2020-04-27 16:11:54 +03:00
function one()
2020-05-01 17:53:35 +03:00
my_global_variable = "hey"
2020-04-27 16:11:54 +03:00
end
2020-05-01 17:53:35 +03:00
print(my_global_variable) -- Output: "ciao"
2020-04-27 16:11:54 +03:00
one()
2020-05-01 17:53:35 +03:00
print(my_global_variable) -- Output: "hey"
2020-04-27 16:11:54 +03:00
```
2020-05-01 17:53:35 +03:00
### Local dovrebbe essere usato il più possibile
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
Lua è globale di default (a differenza di molti altri linguaggi di programmazione).
Le variabili locali devono essere identificate come tali.
2020-04-27 16:11:54 +03:00
```lua
function one()
foo = "bar"
end
function two()
print(dump(foo)) -- Output: "bar"
end
one()
two()
```
2020-08-20 01:49:39 +03:00
dump() è una funzione che può trasformare qualsiasi variabile in una stringa, cosicché il programmatore possa vedere cosa rappresenta.
In questo caso `foo` sarà stampata come "bar", virgolette incluse (che dimostrano che è una stringa).
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
L'esempio precedente non è tuttavia buona norma e Minetest, infatti, ci avviserà di ciò:
2020-04-27 16:11:54 +03:00
Assignment to undeclared global 'foo' inside function at init.lua:2
2020-05-01 17:53:35 +03:00
Per ovviare, usa "local":
2020-04-27 16:11:54 +03:00
```lua
function one()
local foo = "bar"
end
function two()
print(dump(foo)) -- Output: nil
end
one()
two()
```
2020-05-01 17:53:35 +03:00
Ricorda che nil significa **non inizializzato** .
2020-08-20 01:49:39 +03:00
Ovvero la variabile non è stata ancora assegnata a un valore, non esiste o è stata deinizializzata (cioè impostata a nil)
2020-04-27 16:11:54 +03:00
2020-08-20 01:49:39 +03:00
La stessa cosa vale per le funzioni.
Le funzioni sono variabili di tipo speciale, e dovrebbero essere dichiarate locali, in quanto altre mod potrebbero sennò avere funzioni con lo stesso nome.
2020-04-27 16:11:54 +03:00
```lua
local function foo(bar)
return bar * 2
end
```
2020-05-01 17:53:35 +03:00
Le tabelle API dovrebbero essere usate per permettere ad altre mod di chiamare le funzioni, come in:
2020-04-27 16:11:54 +03:00
```lua
mymod = {}
function mymod.foo(bar)
return "foo" .. bar
end
2020-05-01 17:53:35 +03:00
-- In un'altra mod o script:
2020-04-27 16:11:54 +03:00
mymod.foo("foobar")
```
2020-05-01 17:53:35 +03:00
## Inclusione di altri script Lua
2020-04-27 16:11:54 +03:00
2020-05-01 17:53:35 +03:00
Il metodo consigliato per includere in una mod altri script Lua è usare *dofile* .
2020-04-27 16:11:54 +03:00
```lua
dofile(minetest.get_modpath("modname") .. "/script.lua")
```
2020-05-01 17:53:35 +03:00
Uno script può ritornare un valore, che è utile per condividere variabili locali private:
2020-04-27 16:11:54 +03:00
```lua
-- script.lua
return "Hello world!"
-- init.lua
local ret = dofile(minetest.get_modpath("modname") .. "/script.lua")
print(ret) -- Hello world!
```
2020-05-01 17:53:35 +03:00
Nei capitoli seguenti si parlerà nel dettaglio di come suddividere il codice di una mod.
2020-08-20 01:49:39 +03:00
Tuttavia, per ora l'approccio semplicistico è di avere file differenti per diversi tipi di cose — nodi.lua, craft.lua, oggetti.lua ecc.