Lua - Guida rapida

Lua è un linguaggio di programmazione leggero e estensibile scritto in C. È iniziato come progetto interno nel 1993 da Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes.

È stato progettato fin dall'inizio per essere un software che può essere integrato con il codice scritto in C e altri linguaggi convenzionali. Questa integrazione porta molti vantaggi. Non cerca di fare ciò che C può già fare ma mira ad offrire ciò in cui C non è bravo: una buona distanza dall'hardware, strutture dinamiche, nessuna ridondanza, facilità di test e debugging. Per questo, Lua ha un ambiente sicuro, gestione automatica della memoria e buone strutture per la gestione di stringhe e altri tipi di dati con dimensioni dinamiche.

Caratteristiche

Lua fornisce una serie di caratteristiche uniche che lo distingue dalle altre lingue. Questi includono:

  • Extensible
  • Simple
  • Efficient
  • Portable
  • Libero e aperto

Codice di esempio

print("Hello World!")

Come viene implementato Lua?

Lua è composto da due parti: la parte dell'interprete Lua e il sistema software funzionante. Il sistema software funzionante è una vera e propria applicazione per computer in grado di interpretare programmi scritti nel linguaggio di programmazione Lua. L'interprete Lua è scritto in ANSI C, quindi è altamente portabile e può funzionare su una vasta gamma di dispositivi, dai server di rete di fascia alta ai piccoli dispositivi.

Sia la lingua di Lua che il suo interprete sono maturi, piccoli e veloci. Si è evoluto da altri linguaggi di programmazione e dai migliori standard software. Le dimensioni ridotte ne consentono l'esecuzione su piccoli dispositivi con poca memoria.

Imparare Lua

Il punto più importante durante l'apprendimento di Lua è concentrarsi sui concetti senza perdersi nei suoi dettagli tecnici.

Lo scopo dell'apprendimento di un linguaggio di programmazione è diventare un programmatore migliore; vale a dire diventare più efficaci nella progettazione e implementazione di nuovi sistemi e nel mantenimento di quelli vecchi.

Alcuni usi di Lua

  • Programmazione del gioco

  • Scripting in applicazioni autonome

  • Scripting nel Web

  • Estensioni e componenti aggiuntivi per database come MySQL Proxy e MySQL WorkBench

  • Sistemi di sicurezza come Intrusion Detection System.

Configurazione dell'ambiente locale

Se sei ancora disposto a configurare il tuo ambiente per il linguaggio di programmazione Lua, hai bisogno dei seguenti software disponibili sul tuo computer: (a) Text Editor, (b) The Lua Interpreter e (c) Lua Compiler.

Editor di testo

Hai bisogno di un editor di testo per digitare il tuo programma. Esempi di alcuni editor includono Blocco note di Windows, comando OS Edit, Brief, Epsilon, EMACS e vim o vi.

Il nome e la versione dell'editor di testo possono variare a seconda dei sistemi operativi. Ad esempio, il Blocco note verrà utilizzato su Windows e vim o vi possono essere utilizzati su Windows, Linux o UNIX.

I file che crei con il tuo editor sono chiamati file sorgente e questi file contengono il codice sorgente del programma. I file sorgente per i programmi Lua sono in genere denominati con l'estensione".lua".

L'interprete Lua

È solo un piccolo programma che ti consente di digitare comandi Lua e di eseguirli immediatamente. Arresta l'esecuzione di un file Lua nel caso in cui incontri un errore a differenza di un compilatore che viene eseguito completamente.

Il compilatore Lua

Quando estendiamo Lua ad altri linguaggi / applicazioni, abbiamo bisogno di un kit di sviluppo software con un compilatore compatibile con l'interfaccia del programma applicativo Lua.

Installazione su Windows

Esiste un IDE separato denominato "SciTE" sviluppato per l'ambiente Windows, che può essere scaricato da https://code.google.com/p/luaforwindows/ sezione download.

Esegui il file eseguibile scaricato per installare l'IDE Lua.

Poiché è un IDE, puoi creare e costruire il codice Lua usando lo stesso.

Nel caso in cui sei interessato a installare Lua in modalità riga di comando, devi installare MinGW o Cygwin e quindi compilare e installare Lua in Windows.

Installazione su Linux

Per scaricare e creare Lua, usa il seguente comando:

$ wget http://www.lua.org/ftp/lua-5.2.3.tar.gz $ tar zxf lua-5.2.3.tar.gz
$ cd lua-5.2.3 $ make linux test

Per installare su altre piattaforme come aix, ansi, bsd, generic linux, mingw, posix, solaris sostituendo Linux in make Linux, prova con il nome della piattaforma corrispondente.

Abbiamo un helloWorld.lua, in Lua come segue:

print("Hello World!")

Ora possiamo creare ed eseguire un file Lua, ad esempio helloWorld.lua, passando alla cartella contenente il file usando cd, e quindi usando il seguente comando:

$ lua helloWorld

Possiamo vedere il seguente output.

Hello World!

Installazione su Mac OS X

Per creare / testare Lua in Mac OS X, usa il seguente comando:

$ curl -R -O http://www.lua.org/ftp/lua-5.2.3.tar.gz
$ tar zxf lua-5.2.3.tar.gz $ cd lua-5.2.3
$ make macosx test

In alcuni casi, potresti non aver installato Xcode e gli strumenti della riga di comando. In questi casi, non sarai in grado di utilizzare il comando make. Installa Xcode dal Mac App Store. Quindi vai su Preferenze di Xcode, quindi passa a Download e installa il componente denominato "Strumenti della riga di comando". Una volta completato il processo, il comando make sarà disponibile per te.

Non è obbligatorio eseguire l'istruzione "make macosx test". Anche senza eseguire questo comando, puoi comunque utilizzare Lua in Mac OS X.

Abbiamo un helloWorld.lua, in Lua, come segue:

print("Hello World!")

Ora possiamo creare ed eseguire un file Lua, ad esempio helloWorld.lua, passando alla cartella contenente il file utilizzando cd e quindi utilizzando il seguente comando:

$ lua helloWorld

Possiamo vedere il seguente output:

Hello World!

Lua IDE

Come accennato in precedenza, per Windows SciTE, Lua IDE è l'IDE predefinito fornito dal team di creatori di Lua. L'IDE alternativo disponibile è di ZeroBrane Studio, disponibile su più piattaforme come Windows, Mac e Linux.

Ci sono anche plugin per eclipse che abilitano lo sviluppo di Lua. L'uso di IDE semplifica lo sviluppo con funzionalità come il completamento del codice ed è altamente raccomandato. L'IDE fornisce anche una programmazione in modalità interattiva simile alla versione a riga di comando di Lua.

Cominciamo a creare il nostro primo programma Lua!

Primo programma Lua

Programmazione in modalità interattiva

Lua fornisce una modalità chiamata modalità interattiva. In questa modalità, puoi digitare le istruzioni una dopo l'altra e ottenere risultati immediati. Questo può essere richiamato nella shell usando lua -i o semplicemente il comando lua. Dopo aver digitato questo, premere Invio e verrà avviata la modalità interattiva come mostrato di seguito.

$ lua -i $ Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
quit to end; cd, dir and edit also available

Puoi stampare qualcosa usando la seguente dichiarazione:

print("test")

Dopo aver premuto Invio, otterrai il seguente output:

test

Programmazione in modalità predefinita

Invocare l'interprete con un parametro del nome file Lua avvia l'esecuzione del file e continua fino al termine dello script. Quando lo script è finito, l'interprete non è più attivo.

Scriviamo un semplice programma Lua. Tutti i file Lua avranno estensione .lua. Quindi inserisci il seguente codice sorgente in un file test.lua.

print("test")

Supponendo che l'ambiente lua sia configurato correttamente, eseguiamo il programma utilizzando il codice seguente:

$ lua test.lua

Otterremo il seguente output:

test

Proviamo un altro modo per eseguire un programma Lua. Di seguito è riportato il file test.lua modificato -

#!/usr/local/bin/lua

print("test")

Qui, abbiamo assunto che tu abbia l'interprete Lua disponibile nella tua directory / usr / local / bin. La prima riga viene ignorata dall'interprete, se inizia con il segno #. Ora, prova a eseguire questo programma come segue:

$ chmod a+rx test.lua
$./test.lua

Otterremo il seguente output.

test

Vediamo ora la struttura di base del programma Lua, in modo che sarà facile per te comprendere gli elementi costitutivi di base del linguaggio di programmazione Lua.

Gettoni in Lua

Un programma Lua è costituito da vari token e un token può essere una parola chiave, un identificatore, una costante, una stringa letterale o un simbolo. Ad esempio, la seguente istruzione Lua è composta da tre token:

io.write("Hello world, from ",_VERSION,"!\n")

I gettoni individuali sono:

io.write
(
   "Hello world, from ",_VERSION,"!\n"
)

Commenti

I commenti sono come aiutare il testo nel tuo programma Lua e vengono ignorati dall'interprete. Iniziano con - [[e terminano con i caratteri -]] come mostrato di seguito -

--[[ my first program in Lua --]]

Identificatori

Un identificatore Lua è un nome utilizzato per identificare una variabile, una funzione o qualsiasi altro elemento definito dall'utente. Un identificatore inizia con una lettera "dalla A alla Z" o "dalla a alla z" o un trattino basso "_" seguito da zero o più lettere, trattini bassi e cifre (da 0 a 9).

Lua non consente caratteri di punteggiatura come @, $ e% all'interno degli identificatori. Lua è uncase sensitivelinguaggio di programmazione. Quindi Manpower e manpower sono due identificatori diversi in Lua. Di seguito sono riportati alcuni esempi di identificatori accettabili:

mohd         zara      abc     move_name    a_123
myname50     _temp     j       a23b9        retVal

Parole chiave

Il seguente elenco mostra alcune delle parole riservate in Lua. Queste parole riservate non possono essere utilizzate come costanti o variabili o altri nomi di identificatori.

e rompere fare altro
elseif fine falso per
funzione Se in Locale
zero non o ripetere
ritorno poi vero fino a
mentre

Spazio bianco in Lua

Una riga contenente solo spazi bianchi, possibilmente con un commento, è conosciuta come una riga vuota e un interprete Lua la ignora completamente.

Lo spazio bianco è il termine utilizzato in Lua per descrivere spazi vuoti, tabulazioni, caratteri di nuova riga e commenti. Lo spazio vuoto separa una parte di un'istruzione da un'altra e consente all'interprete di identificare dove finisce un elemento in un'istruzione, come int, e inizia l'elemento successivo. Pertanto, nella seguente dichiarazione:

local age

Ci deve essere almeno un carattere di spazio (di solito uno spazio) tra locale ed età affinché l'interprete possa distinguerli. D'altra parte, nella seguente dichiarazione:

fruit = apples + oranges   --get the total fruit

Non sono necessari caratteri di spazi bianchi tra frutta e =, o tra = e mele, sebbene tu sia libero di includerne alcuni se lo desideri per motivi di leggibilità.

Una variabile non è altro che un nome dato a un'area di memoria che i nostri programmi possono manipolare. Può contenere diversi tipi di valori, comprese funzioni e tabelle.

Il nome di una variabile può essere composto da lettere, cifre e il carattere di sottolineatura. Deve iniziare con una lettera o un trattino basso. Le lettere maiuscole e minuscole sono distinte perché Lua fa distinzione tra maiuscole e minuscole. Esistono otto tipi di valori di base in Lua:

In Lua, sebbene non abbiamo tipi di dati variabili, abbiamo tre tipi basati sull'ambito della variabile.

  • Global variables - Tutte le variabili sono considerate globali a meno che non siano esplicitamente dichiarate come locali.

  • Local variables - Quando il tipo è specificato come locale per una variabile, il suo ambito è limitato dalle funzioni all'interno del loro ambito.

  • Table fields - Questo è un tipo speciale di variabile che può contenere qualsiasi cosa tranne zero comprese le funzioni.

Definizione variabile in Lua

Una definizione di variabile significa dire all'interprete dove e quanto creare la memoria per la variabile. Una definizione di variabile ha un tipo facoltativo e contiene un elenco di una o più variabili di quel tipo come segue:

type variable_list;

Qui, type è facoltativamente locale o il tipo specificato rendendolo globale e variable_listpuò essere costituito da uno o più nomi di identificatori separati da virgole. Alcune dichiarazioni valide sono mostrate qui -

local    i, j
local    i
local    a,c

La linea local i, jentrambi dichiara e definisce le variabili i e j; che istruisce l'interprete a creare variabili denominate i, j e limita l'ambito a essere locale.

Le variabili possono essere inizializzate (assegnato un valore iniziale) nella loro dichiarazione. L'inizializzatore è costituito da un segno di uguale seguito da un'espressione costante come segue:

type variable_list = value_list;

Alcuni esempi sono:

local d , f = 5 ,10     --declaration of d and f as local variables. 
d , f = 5, 10;          --declaration of d and f as global variables. 
d, f = 10               --[[declaration of d and f as global variables. 
                           Here value of f is nil --]]

Per la definizione senza un inizializzatore: le variabili con durata di memorizzazione statica vengono inizializzate implicitamente con nil.

Dichiarazione delle variabili in Lua

Come puoi vedere negli esempi precedenti, le assegnazioni per le variabili multiple seguono un formato variabile_elenco e valore_elenco. Nell'esempio sopralocal d, f = 5,10 abbiamo d e f in variable_list e 5 e 10 in value list.

L'assegnazione del valore in Lua avviene come la prima variabile in variable_list con il primo valore in value_list e così via. Quindi, il valore di d è 5 e il valore di f è 10.

Esempio

Prova il seguente esempio, dove le variabili sono state dichiarate in alto, ma sono state definite e inizializzate all'interno della funzione principale -

-- Variable definition:
local a, b

-- Initialization
a = 10
b = 30

print("value of a:", a)

print("value of b:", b)

-- Swapping of variables
b, a = a, b

print("value of a:", a)

print("value of b:", b)

f = 70.0/3.0
print("value of f", f)

Quando il codice precedente viene creato ed eseguito, produce il seguente risultato:

value of a:	10
value of b:	30
value of a:	30
value of b:	10
value of f	23.333333333333

Lvalues ​​e Rvalues ​​in Lua

Ci sono due tipi di espressioni in Lua:

  • lvalue- Le espressioni che fanno riferimento a una posizione di memoria sono chiamate espressione "lvalue". Un lvalue può essere visualizzato sia come lato sinistro che come lato destro di un compito.

  • rvalue- Il termine rvalue si riferisce a un valore di dati archiviato in un indirizzo in memoria. Un rvalue è un'espressione a cui non può essere assegnato un valore, il che significa che un rvalue può apparire sul lato destro, ma non sul lato sinistro di un compito.

Le variabili sono i valori e quindi possono apparire sul lato sinistro di un compito. I letterali numerici sono rvalues ​​e quindi potrebbero non essere assegnati e non possono essere visualizzati sul lato sinistro. La seguente è una dichiarazione valida:

g = 20

Ma la seguente non è un'affermazione valida e genererebbe un errore in fase di compilazione -

10 = 20

Nel linguaggio di programmazione Lua, a parte i suddetti tipi di assegnazione, è possibile avere più lvalue e rvalues ​​nella stessa singola istruzione. È mostrato di seguito.

g,l = 20,30

Nell'affermazione precedente, 20 è assegnato a g e 30 è assegnato a l.

Lua è un linguaggio tipizzato dinamicamente, quindi le variabili non hanno tipi, solo i valori hanno tipi. I valori possono essere memorizzati in variabili, passati come parametri e restituiti come risultati.

In Lua, sebbene non abbiamo tipi di dati variabili, ma abbiamo tipi per i valori. Di seguito viene fornito l'elenco dei tipi di dati per i valori.

Suor n Tipo di valore e descrizione
1

nil

Utilizzato per differenziare il valore dall'avere alcuni dati o nessun dato (zero).

2

boolean

Include vero e falso come valori. Generalmente utilizzato per il controllo delle condizioni.

3

number

Rappresenta numeri reali (virgola mobile a doppia precisione).

4

string

Rappresenta un array di caratteri.

5

function

Rappresenta un metodo scritto in C o Lua.

6

userdata

Rappresenta dati C arbitrari.

7

thread

Rappresenta thread di esecuzione indipendenti e viene utilizzato per implementare le coroutine.

8

table

Rappresenta array ordinari, tabelle di simboli, set, record, grafici, alberi, ecc. E implementa array associativi. Può contenere qualsiasi valore (eccetto zero).

Tipo di funzione

In Lua, c'è una funzione chiamata 'tipo' che ci permette di conoscere il tipo di variabile. Alcuni esempi sono forniti nel codice seguente.

print(type("What is my type"))   --> string
t = 10

print(type(5.8*t))               --> number
print(type(true))                --> boolean
print(type(print))               --> function
print(type(nil))                 --> nil
print(type(type(ABC)))           --> string

Quando crei ed esegui il programma sopra, produce il seguente risultato su Linux:

string
number
boolean
function
nil
string

Per impostazione predefinita, tutte le variabili punteranno a zero fino a quando non viene assegnato un valore o inizializzate. In Lua, le stringhe zero e vuote sono considerate vere in caso di verifica delle condizioni. Quindi, devi stare attento quando usi le operazioni booleane. Ne sapremo di più usando questi tipi nei prossimi capitoli.

Un operatore è un simbolo che dice all'interprete di eseguire specifiche manipolazioni matematiche o logiche. Il linguaggio Lua è ricco di operatori incorporati e fornisce i seguenti tipi di operatori:

  • Operatori aritmetici
  • Operatori relazionali
  • Operatori logici
  • Operatori vari

Questo tutorial spiegherà uno per uno gli operatori aritmetici, relazionali, logici e altri vari.

Operatori aritmetici

La tabella seguente mostra tutti gli operatori aritmetici supportati dal linguaggio Lua. Assumi variabileA detiene 10 e variabile B tiene 20 quindi -

Mostra esempi

Operatore Descrizione Esempio
+ Aggiunge due operandi A + B darà 30
- Sottrae il secondo operando dal primo A - B darà -10
* Moltiplica entrambi gli operandi A * B darà 200
/ Dividi il numeratore per il de-numeratore B / A darà 2
% Operatore modulo e resto di dopo una divisione intera B% A darà 0
^ L'operatore esponente prende gli esponenti Un ^ 2 darà 100
- Unario: l'operatore funge da negazione -A darà -10

Operatori relazionali

La tabella seguente mostra tutti gli operatori relazionali supportati dal linguaggio Lua. Assumi variabileA detiene 10 e variabile B tiene 20 quindi -

Mostra esempi

Operatore Descrizione Esempio
== Controlla se il valore di due operandi è uguale o meno, in caso affermativo la condizione diventa vera. (A == B) non è vero.
~ = Controlla se il valore di due operandi è uguale o meno, se i valori non sono uguali la condizione diventa vera. (A ~ = B) è vero.
> Controlla se il valore dell'operando sinistro è maggiore del valore dell'operando destro, in caso affermativo la condizione diventa vera. (A> B) non è vero.
< Controlla se il valore dell'operando sinistro è inferiore al valore dell'operando destro, in caso affermativo la condizione diventa vera. (A <B) è vero.
> = Controlla se il valore dell'operando sinistro è maggiore o uguale al valore dell'operando destro, in caso affermativo la condizione diventa vera. (A> = B) non è vero.
<= Controlla se il valore dell'operando sinistro è minore o uguale al valore dell'operando destro, in caso affermativo la condizione diventa vera. (A <= B) è vero.

Operatori logici

La tabella seguente mostra tutti gli operatori logici supportati dal linguaggio Lua. Assumi variabileA è vero e variabile B è falso allora -

Mostra esempi

Operatore Descrizione Esempio
e Chiamato operatore AND logico. Se entrambi gli operandi sono diversi da zero, la condizione diventa vera. (A e B) è falso.
o Chiamato Operatore OR logico. Se uno dei due operandi è diverso da zero, la condizione diventa vera. (A o B) è vero.
non Chiamato operatore NOT logico. Utilizzare per invertire lo stato logico del suo operando. Se una condizione è vera, l'operatore NOT logico la renderà falsa. ! (A e B) è vero.

Operatori vari

Gli operatori vari supportati da Lua Language includono concatenation e length.

Mostra esempi

Operatore Descrizione Esempio
.. Concatena due stringhe. a..b dove a è "Hello" eb è "World", restituirà "Hello World".
# Un operatore unario che restituisce la lunghezza di una stringa o di una tabella. # "Hello" restituirà 5

Precedenza degli operatori in Lua

La precedenza degli operatori determina il raggruppamento dei termini in un'espressione. Ciò influisce sul modo in cui viene valutata un'espressione. Alcuni operatori hanno la precedenza maggiore di altri; ad esempio, l'operatore di moltiplicazione ha una precedenza maggiore dell'operatore di addizione -

Ad esempio, x = 7 + 3 * 2; Qui a x viene assegnato 13, non 20 perché l'operatore * ha una precedenza maggiore di +, quindi viene prima moltiplicato per 3 * 2 e poi somma in 7.

Qui, gli operatori con la precedenza più alta vengono visualizzati nella parte superiore della tabella, quelli con la priorità più bassa in fondo. All'interno di un'espressione, verranno valutati per primi gli operatori con precedenza più alta.

Mostra esempi

Categoria Operatore Associatività
Unario non # - Da destra a sinistra
Concatenazione .. Da destra a sinistra
Moltiplicativo * /% Da sinistra a destra
Additivo + - Da sinistra a destra
Relazionale <> <=> = == ~ =  Da sinistra a destra
Uguaglianza == ~ = Da sinistra a destra
AND logico e Da sinistra a destra
OR logico o Da sinistra a destra

Potrebbe esserci una situazione in cui è necessario eseguire un blocco di codice più volte. In generale, le istruzioni vengono eseguite in sequenza: la prima istruzione in una funzione viene eseguita per prima, seguita dalla seconda e così via.

I linguaggi di programmazione forniscono varie strutture di controllo che consentono percorsi di esecuzione più complicati.

Un'istruzione loop ci consente di eseguire un'istruzione o un gruppo di istruzioni più volte. Di seguito è riportata la forma generale di un'istruzione loop nella maggior parte dei linguaggi di programmazione:

Lua fornisce i seguenti tipi di loop per gestire i requisiti di loop.

Sr.No. Tipo e descrizione del loop
1 while loop

Ripete un'istruzione o un gruppo di istruzioni finché una determinata condizione è vera. Verifica la condizione prima di eseguire il corpo del ciclo.

2 per loop

Esegue una sequenza di istruzioni più volte e abbrevia il codice che gestisce la variabile del ciclo.

3 ripetere ... fino al ciclo

Ripete l'operazione di gruppo di istruzioni finché non viene soddisfatta la condizione until.

4 loop annidati

È possibile utilizzare uno o più cicli all'interno di un altro ciclo while, for o do .. while .

Dichiarazione di controllo del ciclo

L'istruzione di controllo del ciclo cambia l'esecuzione dalla sua sequenza normale. Quando l'esecuzione esce da un ambito, tutti gli oggetti automatici creati in tale ambito vengono eliminati.

Lua supporta le seguenti istruzioni di controllo.

Sr.No. Dichiarazione di controllo e descrizione
1 dichiarazione di interruzione

Termina il loop e trasferisce l'esecuzione all'istruzione immediatamente successiva al ciclo o allo switch.

Il ciclo infinito

Un ciclo diventa ciclo infinito se una condizione non diventa mai falsa. Ilwhileloop viene spesso utilizzato per questo scopo. Poiché forniamo direttamente true per la condizione, continua a essere eseguita per sempre. Possiamo usare l'istruzione break per interrompere questo ciclo.

while( true )
do
   print("This loop will run forever.")
end

Le strutture decisionali richiedono che il programmatore specifichi una o più condizioni che devono essere valutate o testate dal programma, insieme a una o più istruzioni da eseguire, se la condizione è determinata essere vera, e facoltativamente, altre istruzioni da eseguire se il condizione è determinata essere falsa.

Di seguito è riportata la forma generale di una tipica struttura decisionale presente nella maggior parte dei linguaggi di programmazione:

Il linguaggio di programmazione Lua presuppone qualsiasi combinazione di booleano true e non-nil valori come truee se è booleano false o nil, quindi si assume come falsevalore. È da notare che a Lua,zero will be considered as true.

Il linguaggio di programmazione Lua fornisce i seguenti tipi di dichiarazioni decisionali.

Sr.No. Dichiarazione e descrizione
1 istruzione if

Un'istruzione if è costituita da un'espressione booleana seguita da una o più istruzioni.

2 if ... else dichiarazione

Un'istruzione if può essere seguita da un'istruzione else opzionale , che viene eseguita quando l'espressione booleana è falsa.

3 istruzioni if ​​annidate

È possibile utilizzare un'istruzione if o else if all'interno di un'altra istruzione if o else if .

Una funzione è un gruppo di istruzioni che insieme eseguono un'attività. Puoi dividere il tuo codice in funzioni separate. Come suddividere il codice tra le diverse funzioni dipende da te, ma logicamente la divisione di solito è unica, quindi ogni funzione esegue un compito specifico.

Il linguaggio Lua fornisce numerosi metodi incorporati che il tuo programma può chiamare. Ad esempio, metodoprint() per stampare l'argomento passato come input nella console.

Una funzione è nota con vari nomi come un metodo, una sottoprogramma o una procedura ecc.

Definizione di una funzione

La forma generale della definizione di un metodo nel linguaggio di programmazione Lua è la seguente:

optional_function_scope function function_name( argument1, argument2, argument3........, 
argumentn)
function_body
return result_params_comma_separated
end

Una definizione di metodo nel linguaggio di programmazione Lua consiste in un'intestazione del metodo e un corpo del metodo . Ecco tutte le parti di un metodo:

  • Optional Function Scope- È possibile utilizzare la parola chiave local per limitare l'ambito della funzione o ignorare la sezione dell'ambito, che la renderà una funzione globale.

  • Function Name- Questo è il nome effettivo della funzione. Il nome della funzione e l'elenco dei parametri insieme costituiscono la firma della funzione.

  • Arguments- Un argomento è come un segnaposto. Quando viene invocata una funzione, si passa un valore all'argomento. Questo valore viene definito parametro o argomento effettivo. L'elenco dei parametri fa riferimento al tipo, all'ordine e al numero degli argomenti di un metodo. Gli argomenti sono facoltativi; ovvero, un metodo non può contenere argomenti.

  • Function Body - Il corpo del metodo contiene una raccolta di istruzioni che definiscono ciò che fa il metodo.

  • Return - In Lua, è possibile restituire più valori seguendo la parola chiave return con i valori di ritorno separati da virgole.

Esempio

Di seguito è riportato il codice sorgente di una funzione chiamata max(). Questa funzione accetta due parametri num1 e num2 e restituisce il massimo tra i due -

--[[ function returning the max between two numbers --]]
function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   return result; 
end

Argomenti della funzione

Se una funzione deve utilizzare argomenti, deve dichiarare le variabili che accettano i valori degli argomenti. Queste variabili sono chiamateformal parameters della funzione.

I parametri formali si comportano come le altre variabili locali all'interno della funzione e vengono creati all'ingresso nella funzione e distrutti all'uscita.

Chiamare una funzione

Durante la creazione di una funzione Lua, dai una definizione di ciò che la funzione deve fare. Per utilizzare un metodo, dovrai chiamare quella funzione per eseguire l'attività definita.

Quando un programma chiama una funzione, il controllo del programma viene trasferito alla funzione chiamata. Una funzione chiamata esegue l'attività definita e quando viene eseguita la sua istruzione return o quando viene raggiunta la fine della sua funzione, restituisce il controllo del programma al programma principale.

Per chiamare un metodo, è sufficiente passare i parametri richiesti insieme al nome del metodo e se il metodo restituisce un valore, è possibile memorizzare il valore restituito. Ad esempio:

function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   return result; 
end

-- calling a function
print("The maximum of the two numbers is ",max(10,4))
print("The maximum of the two numbers is ",max(5,6))

Quando eseguiamo il codice sopra, otterremo il seguente output.

The maximum of the two numbers is 	10
The maximum of the two numbers is 	6

Assegnazione e passaggio di funzioni

In Lua, possiamo assegnare la funzione a variabili e anche passarle come parametri di un'altra funzione. Ecco un semplice esempio per l'assegnazione e il passaggio di una funzione come parametro in Lua.

myprint = function(param)
   print("This is my print function -   ##",param,"##")
end

function add(num1,num2,functionPrint)
   result = num1 + num2
   functionPrint(result)
end

myprint(10)
add(2,5,myprint)

Quando eseguiamo il codice sopra, otterremo il seguente output.

This is my print function -   ##	10	##
This is my print function -   ##	7	##

Funzione con argomento variabile

È possibile creare funzioni con argomenti variabili in Lua utilizzando "..." come parametro. Possiamo comprenderlo vedendo un esempio in cui la funzione restituirà la media e può accettare argomenti variabili.

function average(...)
   result = 0
   local arg = {...}
   for i,v in ipairs(arg) do
      result = result + v
   end
   return result/#arg
end

print("The average is",average(10,5,3,4,5,6))

Quando eseguiamo il codice sopra, otterremo il seguente output.

The average is	5.5

La stringa è una sequenza di caratteri e caratteri di controllo come feed modulo. La stringa può essere inizializzata con tre forme che includono:

  • Caratteri tra virgolette singole
  • Caratteri tra virgolette doppie
  • Caratteri tra [[e]]

Di seguito è riportato un esempio per le tre forme precedenti.

string1 = "Lua"
print("\"String 1 is\"",string1)

string2 = 'Tutorial'
print("String 2 is",string2)

string3 = [["Lua Tutorial"]]
print("String 3 is",string3)

Quando eseguiamo il programma sopra, otterremo il seguente output.

"String 1 is" Lua
String 2 is	Tutorial
String 3 is	"Lua Tutorial"

I caratteri della sequenza di escape vengono utilizzati nella stringa per modificare la normale interpretazione dei caratteri. Ad esempio, per stampare doppie virgolette (""), abbiamo usato \ "nell'esempio precedente. La sequenza di escape e il suo utilizzo sono elencati di seguito nella tabella.

Sequenza di fuga Uso
\un campana
\ b Backspace
\ f Formfeed
\ n Nuova linea
\ r Ritorno in carrozza
\ t Tab
\ v Scheda verticale
\\ Barra rovesciata
\ " Virgolette
\ ' Virgolette singole
\ [ Parentesi quadra sinistra
\] Parentesi quadra destra

Manipolazione delle stringhe

Lua supporta le stringhe per manipolare le stringhe -

Sr.No. Metodo e scopo
1

string.upper(argument)

Restituisce una rappresentazione in maiuscolo dell'argomento.

2

string.lower(argument)

Restituisce una rappresentazione minuscola dell'argomento.

3

string.gsub(mainString,findString,replaceString)

Restituisce una stringa sostituendo le occorrenze di findString con replaceString.

4

string.find(mainString,findString,

optionalStartIndex,optionalEndIndex)

Restituisce l'indice iniziale e l'indice finale della findString nella stringa principale e nil se non trovato.

5

string.reverse(arg)

Restituisce una stringa invertendo i caratteri della stringa passata.

6

string.format(...)

Restituisce una stringa formattata.

7

string.char(arg) and string.byte(arg)

Restituisce rappresentazioni numeriche e di caratteri interne dell'argomento di input.

8

string.len(arg)

Restituisce una lunghezza della stringa passata.

9

string.rep(string, n))

Restituisce una stringa ripetendo la stessa stringa n numero di volte.

10

..

Quindi l'operatore concatena due stringhe.

Ora, esaminiamo alcuni esempi per vedere esattamente come si comportano queste funzioni di manipolazione delle stringhe.

Manipolazione dei casi

Di seguito viene fornito un codice di esempio per la modifica delle stringhe in lettere maiuscole e minuscole.

string1 = "Lua";

print(string.upper(string1))
print(string.lower(string1))

Quando eseguiamo il programma sopra, otterremo il seguente output.

LUA
lua

Sostituzione di una sottostringa

Di seguito viene fornito un codice di esempio per la sostituzione delle occorrenze di una stringa con un'altra.

string = "Lua Tutorial"

-- replacing strings
newstring = string.gsub(string,"Tutorial","Language")
print("The new string is "..newstring)

Quando eseguiamo il programma sopra, otterremo il seguente output.

The new string is Lua Language

Trovare e invertire

Di seguito viene fornito un codice di esempio per la ricerca dell'indice della sottostringa e della stringa di inversione.

string = "Lua Tutorial"

-- replacing strings
print(string.find(string,"Tutorial"))
reversedString = string.reverse(string)
print("The new string is",reversedString)

Quando eseguiamo il programma sopra, otterremo il seguente output.

5	12
The new string is	lairotuT auL

Formattazione delle stringhe

Molte volte nella nostra programmazione, potrebbe essere necessario stampare le stringhe in modo formattato. È possibile utilizzare la funzione string.format per formattare l'output come mostrato di seguito.

string1 = "Lua"
string2 = "Tutorial"

number1 = 10
number2 = 20

-- Basic string formatting
print(string.format("Basic formatting %s %s",string1,string2))

-- Date formatting
date = 2; month = 1; year = 2014
print(string.format("Date formatting %02d/%02d/%03d", date, month, year))

-- Decimal formatting
print(string.format("%.4f",1/3))

Quando eseguiamo il programma sopra, otterremo il seguente output.

Basic formatting Lua Tutorial
Date formatting 02/01/2014
0.3333

Rappresentazioni di caratteri e byte

Un codice di esempio per la rappresentazione di caratteri e byte, utilizzato per convertire la stringa da stringa a rappresentazione interna e viceversa.

-- Byte conversion

-- First character
print(string.byte("Lua"))

-- Third character
print(string.byte("Lua",3))

-- first character from last
print(string.byte("Lua",-1))

-- Second character
print(string.byte("Lua",2))

-- Second character from last
print(string.byte("Lua",-2))

-- Internal Numeric ASCII Conversion
print(string.char(97))

Quando eseguiamo il programma sopra, otterremo il seguente output.

76
97
97
117
117
a

Altre funzioni comuni

Le manipolazioni di stringhe comuni includono la concatenazione di stringhe, la ricerca della lunghezza della stringa e, a volte, la ripetizione della stessa stringa più volte. L'esempio di queste operazioni è fornito di seguito.

string1 = "Lua"
string2 = "Tutorial"

-- String Concatenations using ..
print("Concatenated string",string1..string2)

-- Length of string
print("Length of string1 is ",string.len(string1))

-- Repeating strings
repeatedString = string.rep(string1,3)
print(repeatedString)

Quando eseguiamo il programma sopra, otterremo il seguente output.

Concatenated string	LuaTutorial
Length of string1 is 	3
LuaLuaLua

Gli array sono disposizioni ordinate di oggetti, che possono essere un array unidimensionale contenente una raccolta di righe o un array multidimensionale contenente più righe e colonne.

In Lua, gli array vengono implementati utilizzando tabelle di indicizzazione con numeri interi. La dimensione di un array non è fissa e può crescere in base ai nostri requisiti, soggetti a vincoli di memoria.

Array unidimensionale

Un array unidimensionale può essere rappresentato utilizzando una semplice struttura di tabella e può essere inizializzato e letto utilizzando un semplice file forciclo continuo. Di seguito è mostrato un esempio.

array = {"Lua", "Tutorial"}

for i = 0, 2 do
   print(array[i])
end

Quando eseguiamo il codice sopra, otterremo il seguente output.

nil
Lua
Tutorial

Come puoi vedere nel codice sopra, quando stiamo cercando di accedere a un elemento in un indice che non è presente nell'array, restituisce nil. In Lua, l'indicizzazione inizia generalmente dall'indice 1. Ma è possibile creare oggetti anche dall'indice 0 e sotto lo 0. L'array che usa indici negativi è mostrato di seguito dove inizializziamo l'array usando un ciclo for .

array = {}

for i= -2, 2 do
   array[i] = i *2
end

for i = -2,2 do
   print(array[i])
end

Quando eseguiamo il codice sopra, otterremo il seguente output.

-4
-2
0
2
4

Array multidimensionale

Gli array multidimensionali possono essere implementati in due modi.

  • Array di array
  • Matrice unidimensionale manipolando gli indici

Di seguito viene mostrato un esempio di array multidimensionale di 3. 3 utilizzando array di array.

-- Initializing the array
array = {}

for i=1,3 do
   array[i] = {}
	
   for j=1,3 do
      array[i][j] = i*j
   end
	
end

-- Accessing the array

for i=1,3 do

   for j=1,3 do
      print(array[i][j])
   end
	
end

Quando eseguiamo il codice sopra, otterremo il seguente output.

1
2
3
2
4
6
3
6
9

Di seguito è mostrato un esempio di array multidimensionale utilizzando indici di manipolazione.

-- Initializing the array

array = {}

maxRows = 3
maxColumns = 3

for row=1,maxRows do

   for col=1,maxColumns do
      array[row*maxColumns +col] = row*col
   end
	
end

-- Accessing the array

for row=1,maxRows do

   for col=1,maxColumns do
      print(array[row*maxColumns +col])
   end
	
end

Quando eseguiamo il codice sopra, otterremo il seguente output.

1
2
3
2
4
6
3
6
9

Come puoi vedere nell'esempio sopra, i dati vengono memorizzati sulla base di indici. È possibile posizionare gli elementi in modo sparso ed è il modo in cui funziona l'implementazione Lua di una matrice. Dal momento che non memorizza valori nulli in Lua, è possibile risparmiare molta memoria senza alcuna tecnica speciale in Lua rispetto alle tecniche speciali utilizzate in altri linguaggi di programmazione.

Iterator è un costrutto che consente di attraversare gli elementi della cosiddetta raccolta o contenitore. In Lua, queste raccolte fanno spesso riferimento a tabelle, che vengono utilizzate per creare varie strutture di dati come array.

Generico per iteratore

Un generico per iteratore fornisce le coppie chiave-valore di ogni elemento nella raccolta. Di seguito viene fornito un semplice esempio.

array = {"Lua", "Tutorial"}

for key,value in ipairs(array) 
do
   print(key, value)
end

Quando eseguiamo il codice sopra, otterremo il seguente output:

1  Lua
2  Tutorial

L'esempio precedente utilizza la funzione iteratore ipairs predefinita fornita da Lua.

In Lua usiamo le funzioni per rappresentare gli iteratori. In base al mantenimento dello stato in queste funzioni iteratore, abbiamo due tipi principali:

  • Iteratori apolidi
  • Iteratori con stato

Iteratori apolidi

Dal nome stesso possiamo capire che questo tipo di funzione iteratore non mantiene alcuno stato.

Vediamo ora un esempio di creazione del nostro iteratore utilizzando una semplice funzione che stampa i quadrati di n numeri.

function square(iteratorMaxCount,currentNumber)

   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
      return currentNumber, currentNumber*currentNumber
   end
	
end

for i,n in square,3,0
do
   print(i,n)
end

Quando eseguiamo il programma sopra, otterremo il seguente output.

1	1
2	4
3	9

Il codice sopra può essere leggermente modificato per imitare il modo in cui funzionano le funzioni ipairs degli iteratori. È mostrato di seguito.

function square(iteratorMaxCount,currentNumber)

   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
      return currentNumber, currentNumber*currentNumber
   end
	
end

function squares(iteratorMaxCount)
   return square,iteratorMaxCount,0
end  

for i,n in squares(3)
do 
   print(i,n)
end

Quando eseguiamo il programma sopra, otterremo il seguente output.

1	1
2	4
3	9

Iteratori con stato

L'esempio precedente di iterazione utilizzando la funzione non mantiene lo stato. Ogni volta che la funzione viene chiamata, restituisce l'elemento successivo della raccolta in base a una seconda variabile inviata alla funzione. Per mantenere lo stato dell'elemento corrente, vengono utilizzate le chiusure. La chiusura conserva i valori delle variabili tra le chiamate di funzioni. Per creare una nuova chiusura, creiamo due funzioni tra cui la chiusura stessa e una fabbrica, la funzione che crea la chiusura.

Vediamo ora un esempio di creazione del nostro iteratore in cui useremo le chiusure.

array = {"Lua", "Tutorial"}

function elementIterator (collection)

   local index = 0
   local count = #collection
	
   -- The closure function is returned
	
   return function ()
      index = index + 1
		
      if index <= count
      then
         -- return the current element of the iterator
         return collection[index]
      end
		
   end
	
end

for element in elementIterator(array)
do
   print(element)
end

Quando eseguiamo il programma sopra, otterremo il seguente output.

Lua
Tutorial

Nell'esempio precedente, possiamo vedere che elementIterator ha un altro metodo all'interno che utilizza l'indice e il conteggio delle variabili esterne locali per restituire ciascuno degli elementi nella raccolta incrementando l'indice ogni volta che viene chiamata la funzione.

Possiamo creare i nostri iteratori di funzioni usando la chiusura come mostrato sopra e può restituire più elementi per ciascuna delle volte in cui iteriamo nella raccolta.

introduzione

Le tabelle sono l'unica struttura di dati disponibile in Lua che ci aiuta a creare diversi tipi come array e dizionari. Lua utilizza array associativi e che possono essere indicizzati non solo con numeri ma anche con stringhe tranne nil. I tavoli non hanno dimensioni fisse e possono crescere in base alle nostre esigenze.

Lua utilizza le tabelle in tutte le rappresentazioni, inclusa la rappresentazione dei pacchetti. Quando accediamo a un metodo string.format, significa che stiamo accedendo alla funzione di formattazione disponibile nel pacchetto string.

Rappresentazione e utilizzo

Le tabelle sono chiamate oggetti e non sono né valori né variabili. Lua utilizza un'espressione del costruttore {} per creare una tabella vuota. È noto che non esiste una relazione fissa tra una variabile che contiene il riferimento della tabella e la tabella stessa.

--sample table initialization
mytable = {}

--simple table value assignment
mytable[1]= "Lua"

--removing reference
mytable = nil

-- lua garbage collection will take care of releasing memory

Quando abbiamo un tavolo a con un insieme di elementi e se lo assegniamo a b, tutti e due a e bfare riferimento alla stessa memoria. Nessuna memoria separata viene allocata separatamente per b. Quando a è impostato su zero, la tabella sarà ancora accessibile a b. Quando non ci sono riferimenti a una tabella, la garbage collection in Lua si occupa di ripulire il processo per riutilizzare nuovamente la memoria non referenziata.

Di seguito è riportato un esempio per spiegare le caratteristiche delle tabelle sopra menzionate.

-- Simple empty table
mytable = {}
print("Type of mytable is ",type(mytable))

mytable[1]= "Lua"
mytable["wow"] = "Tutorial"

print("mytable Element at index 1 is ", mytable[1])
print("mytable Element at index wow is ", mytable["wow"])

-- alternatetable and mytable refers to same table
alternatetable = mytable

print("alternatetable Element at index 1 is ", alternatetable[1])
print("alternatetable Element at index wow is ", alternatetable["wow"])

alternatetable["wow"] = "I changed it"

print("mytable Element at index wow is ", mytable["wow"])

-- only variable released and and not table
alternatetable = nil
print("alternatetable is ", alternatetable)

-- mytable is still accessible
print("mytable Element at index wow is ", mytable["wow"])

mytable = nil
print("mytable is ", mytable)

Quando eseguiamo il programma sopra, otterremo il seguente output:

Type of mytable is 	table
mytable Element at index 1 is 	Lua
mytable Element at index wow is 	Tutorial
alternatetable Element at index 1 is 	Lua
alternatetable Element at index wow is 	Tutorial
mytable Element at index wow is 	I changed it
alternatetable is 	nil
mytable Element at index wow is 	I changed it
mytable is 	nil

Manipolazione della tabella

Sono presenti funzioni integrate per la manipolazione delle tabelle e sono elencate nella tabella seguente.

Sr.No. Metodo e scopo
1

table.concat (table [, sep [, i [, j]]])

Concatena le stringhe nelle tabelle in base ai parametri forniti. Vedi esempio per i dettagli.

2

table.insert (table, [pos,] value)

Inserisce un valore nella tabella nella posizione specificata.

3

table.maxn (table)

Restituisce l'indice numerico più grande.

4

table.remove (table [, pos])

Rimuove il valore dalla tabella.

5

table.sort (table [, comp])

Ordina la tabella in base all'argomento del comparatore facoltativo.

Vediamo alcuni esempi delle funzioni di cui sopra.

Tabella concatenazione

Possiamo usare la funzione concat per concatenare due tabelle come mostrato di seguito -

fruits = {"banana","orange","apple"}

-- returns concatenated string of table
print("Concatenated string ",table.concat(fruits))

--concatenate with a character
print("Concatenated string ",table.concat(fruits,", "))

--concatenate fruits based on index
print("Concatenated string ",table.concat(fruits,", ", 2,3))

Quando eseguiamo il programma sopra, otterremo il seguente output:

Concatenated string 	bananaorangeapple
Concatenated string 	banana, orange, apple
Concatenated string 	orange, apple

Inserisci e rimuovi

L'inserimento e la rimozione di elementi nelle tabelle è più comune nella manipolazione delle tabelle. È spiegato di seguito.

fruits = {"banana","orange","apple"}

-- insert a fruit at the end
table.insert(fruits,"mango")
print("Fruit at index 4 is ",fruits[4])

--insert fruit at index 2
table.insert(fruits,2,"grapes")
print("Fruit at index 2 is ",fruits[2])

print("The maximum elements in table is",table.maxn(fruits))

print("The last element is",fruits[5])

table.remove(fruits)
print("The previous last element is",fruits[5])

Quando eseguiamo il programma sopra, otterremo il seguente output:

Fruit at index 4 is 	mango
Fruit at index 2 is 	grapes
The maximum elements in table is	5
The last element is	mango
The previous last element is	nil

Tabelle di ordinamento

Spesso abbiamo bisogno di ordinare una tabella in un ordine particolare. Le funzioni di ordinamento ordinano gli elementi in una tabella in ordine alfabetico. Un esempio per questo è mostrato di seguito.

fruits = {"banana","orange","apple","grapes"}

for k,v in ipairs(fruits) do
   print(k,v)
end

table.sort(fruits)
print("sorted table")

for k,v in ipairs(fruits) do
   print(k,v)
end

Quando eseguiamo il programma sopra, otterremo il seguente output:

1	banana
2	orange
3	apple
4	grapes
sorted table
1	apple
2	banana
3	grapes
4	orange

Cos'è un modulo?

Il modulo è come una libreria che può essere caricata utilizzando require e ha un unico nome globale contenente una tabella. Questo modulo può essere costituito da una serie di funzioni e variabili. Tutte queste funzioni e variabili sono inserite nella tabella, che funge da spazio dei nomi. Inoltre, un modulo ben funzionante ha le disposizioni necessarie per restituire questa tabella su require.

Specialità dei moduli Lua

L'utilizzo di tabelle nei moduli ci aiuta in molti modi e ci permette di manipolare i moduli nello stesso modo in cui manipoliamo qualsiasi altra tabella Lua. Come risultato della capacità di manipolare i moduli, fornisce funzionalità extra per le quali altri linguaggi richiedono meccanismi speciali. Grazie a questo meccanismo gratuito di moduli in Lua, un utente può chiamare le funzioni in Lua in diversi modi. Alcuni di loro sono mostrati di seguito.

-- Assuming we have a module printFormatter
-- Also printFormatter has a funtion simpleFormat(arg)
-- Method 1
require "printFormatter"
printFormatter.simpleFormat("test")

-- Method 2
local formatter = require "printFormatter"
formatter.simpleFormat("test")

-- Method 3
require "printFormatter"
local formatterFunction = printFormatter.simpleFormat
formatterFunction("test")

Nel codice di esempio sopra, puoi vedere quanto sia flessibile la programmazione in Lua, senza alcun codice aggiuntivo speciale.

La funzione require

Lua ha fornito una funzione di alto livello chiamata require per caricare tutti i moduli necessari. È mantenuto il più semplice possibile per evitare di avere troppe informazioni sul modulo per caricarlo. La funzione require assume i moduli solo come una porzione di codice che definisce alcuni valori, che in realtà sono funzioni o tabelle che contengono funzioni.

Esempio

Consideriamo un semplice esempio, in cui una funzione ha le funzioni matematiche. Chiamiamo questo modulo mymath e il nome del file è mymath.lua. Il contenuto del file è il seguente:

local mymath =  {}

function mymath.add(a,b)
   print(a+b)
end

function mymath.sub(a,b)
   print(a-b)
end

function mymath.mul(a,b)
   print(a*b)
end

function mymath.div(a,b)
   print(a/b)
end

return mymath

Ora, per accedere a questo modulo Lua in un altro file, ad esempio moduletutorial.lua, devi usare il seguente segmento di codice.

mymathmodule = require("mymath")
mymathmodule.add(10,20)
mymathmodule.sub(30,20)
mymathmodule.mul(10,20)
mymathmodule.div(30,20)

Per eseguire questo codice, è necessario posizionare i due file Lua nella stessa directory o, in alternativa, è possibile posizionare il file del modulo nel percorso del pacchetto e necessita di una configurazione aggiuntiva. Quando eseguiamo il programma sopra, otterremo il seguente output.

30
10
200
1.5

Cose da ricordare

  • Posiziona entrambi i moduli e il file che esegui nella stessa directory.

  • Il nome del modulo e il nome del file dovrebbero essere gli stessi.

  • È una buona pratica restituire i moduli per la funzione require e quindi il modulo dovrebbe essere preferibilmente implementato come mostrato sopra, sebbene sia possibile trovare altri tipi di implementazioni altrove.

Vecchio modo di implementare i moduli

Consentitemi ora di riscrivere lo stesso esempio nel modo precedente, che utilizza il tipo di implementazione package.seeall. Questo è stato utilizzato nelle versioni Lua 5.1 e 5.0. Il modulo di matematica è mostrato di seguito.

module("mymath", package.seeall)

function mymath.add(a,b)
   print(a+b)
end

function mymath.sub(a,b)
   print(a-b)
end

function mymath.mul(a,b)
   print(a*b)
end

function mymath.div(a,b)
   print(a/b)
end

Di seguito è mostrato l'utilizzo dei moduli in moduletutorial.lua.

require("mymath")
mymath.add(10,20)
mymath.sub(30,20)
mymath.mul(10,20)
mymath.div(30,20)

Quando eseguiamo quanto sopra, otterremo lo stesso output. Ma si consiglia di utilizzare la versione precedente del codice e si presume che sia meno sicura. Molti SDK che utilizzano Lua per la programmazione come Corona SDK ne hanno deprecato l'uso.

Un metatable è una tabella che aiuta a modificare il comportamento di una tabella a cui è collegata con l'aiuto di un set di chiavi e dei relativi meta metodi. Questi meta metodi sono potenti funzionalità Lua che abilitano funzionalità come:

  • Modifica / aggiunta di funzionalità agli operatori sulle tabelle.

  • Ricerca di metatables quando la chiave non è disponibile nella tabella utilizzando __index in metatable.

Esistono due metodi importanti utilizzati nella gestione dei metatables che includono:

  • setmetatable(table,metatable) - Questo metodo viene utilizzato per impostare metatable per una tabella.

  • getmetatable(table) - Questo metodo viene utilizzato per ottenere metatable di una tabella.

Diamo prima un'occhiata a come impostare una tabella come metatizzabile di un'altra. È mostrato di seguito.

mytable = {}
mymetatable = {}
setmetatable(mytable,mymetatable)

Il codice sopra può essere rappresentato in una singola riga come mostrato di seguito.

mytable = setmetatable({},{})

_indice

Di seguito è mostrato un semplice esempio di metatable per cercare la meta tabella quando non è disponibile nella tabella.

mytable = setmetatable({key1 = "value1"}, {
   __index = function(mytable, key)
	
      if key == "key2" then
         return "metatablevalue"
      else
         return mytable[key]
      end
   end
})

print(mytable.key1,mytable.key2)

Quando eseguiamo il programma sopra, otterremo il seguente output.

value1 metatablevalue

Cerchiamo di spiegare cosa è successo nell'esempio sopra nei passaggi.

  • Il tavolo mytable qui è {key1 = "value1"}.

  • Metatable è impostato per mytable che contiene una funzione per __index, che chiamiamo metamethod.

  • Il metametodo fa un semplice lavoro di ricerca di un indice "chiave2", se viene trovato, restituisce "metatablevalue", altrimenti restituisce il valore di mytable per l'indice corrispondente.

Possiamo avere una versione semplificata del programma sopra come mostrato di seguito.

mytable = setmetatable({key1 = "value1"}, 
   { __index = { key2 = "metatablevalue" } })
print(mytable.key1,mytable.key2)

__newindex

Quando aggiungiamo __newindex a metatable, se le chiavi non sono disponibili nella tabella, il comportamento delle nuove chiavi sarà definito dai meta metodi. Di seguito viene fornito un semplice esempio in cui l'indice di metatable è impostato quando l'indice non è disponibile nella tabella principale.

mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })

print(mytable.key1)

mytable.newkey = "new value 2"
print(mytable.newkey,mymetatable.newkey)

mytable.key1 = "new  value 1"
print(mytable.key1,mymetatable.newkey1)

Quando esegui il programma sopra, ottieni il seguente output.

value1
nil	new value 2
new  value 1	nil

Puoi vedere nel programma sopra, se una chiave esiste nella tabella principale, la aggiorna semplicemente. Quando una chiave non è disponibile nella tabella principale, aggiunge quella chiave al metatable.

Di seguito è mostrato un altro esempio che aggiorna la stessa tabella utilizzando la funzione rawset.

mytable = setmetatable({key1 = "value1"}, {

   __newindex = function(mytable, key, value)
      rawset(mytable, key, "\""..value.."\"")
   end
})

mytable.key1 = "new value"
mytable.key2 = 4

print(mytable.key1,mytable.key2)

Quando eseguiamo il programma sopra, otterremo il seguente output.

new value	"4"

rawset imposta il valore senza usare __newindex di metatable. Allo stesso modo c'è rawget che ottiene valore senza usare __index.

Aggiunta del comportamento dell'operatore alle tabelle

Di seguito è mostrato un semplice esempio per combinare due tabelle utilizzando l'operatore +:

mytable = setmetatable({ 1, 2, 3 }, {
   __add = function(mytable, newtable)
	
      for i = 1, table.maxn(newtable) do
         table.insert(mytable, table.maxn(mytable)+1,newtable[i])
      end
      return mytable
   end
})

secondtable = {4,5,6}

mytable = mytable + secondtable

for k,v in ipairs(mytable) do
   print(k,v)
end

Quando eseguiamo il programma sopra, otterremo il seguente output.

1	1
2	2
3	3
4	4
5	5
6	6

La chiave __add è inclusa nel metatable per aggiungere il comportamento dell'operatore +. Di seguito è riportata la tabella dei tasti e dell'operatore corrispondente.

Sr.No. Modalità e descrizione
1

__add

Modifica il comportamento dell'operatore "+".

2

__sub

Modifica il comportamento dell'operatore "-".

3

__mul

Modifica il comportamento dell'operatore "*".

4

__div

Modifica il comportamento dell'operatore "/".

5

__mod

Modifica il comportamento dell'operatore '%'.

6

__unm

Modifica il comportamento dell'operatore "-".

7

__concat

Modifica il comportamento dell'operatore "..".

8

__eq

Modifica il comportamento dell'operatore "==".

9

__lt

Modifica il comportamento dell'operatore "<".

10

__le

Modifica il comportamento dell'operatore "<=".

__chiamata

L'aggiunta del comportamento della chiamata al metodo viene eseguita utilizzando l'istruzione __call. Un semplice esempio che restituisce la somma dei valori nella tabella principale con la tabella passata.

mytable = setmetatable({10}, {
   __call = function(mytable, newtable)
   sum = 0
	
      for i = 1, table.maxn(mytable) do
         sum = sum + mytable[i]
      end
	
      for i = 1, table.maxn(newtable) do
         sum = sum + newtable[i]
      end
	
      return sum
   end
})

newtable = {10,20,30}
print(mytable(newtable))

Quando eseguiamo il programma sopra, otterremo il seguente output.

70

__accordare

Per cambiare il comportamento dell'istruzione print, possiamo usare il metametodo __tostring. Di seguito viene mostrato un semplice esempio.

mytable = setmetatable({ 10, 20, 30 }, {
   __tostring = function(mytable)
   sum = 0
	
      for k, v in pairs(mytable) do
         sum = sum + v
      end
		
      return "The sum of values in the table is " .. sum
   end
})
print(mytable)

Quando eseguiamo il programma sopra, otterremo il seguente output.

The sum of values in the table is 60

Se conosci appieno le capacità della meta table, puoi davvero eseguire molte operazioni che sarebbero molto complesse senza usarla. Quindi, prova a lavorare di più sull'uso dei metatables con diverse opzioni disponibili nelle meta tabelle come spiegato negli esempi e crea anche i tuoi campioni.

introduzione

Le coroutine sono di natura collaborativa, il che consente a due o più metodi di essere eseguiti in modo controllato. Con le coroutine, in un dato momento, viene eseguita solo una coroutine e questa coroutine in esecuzione sospende la sua esecuzione solo quando richiede esplicitamente di essere sospesa.

La definizione di cui sopra può sembrare vaga. Supponiamo di avere due metodi, uno il metodo del programma principale e una coroutine. Quando chiamiamo una coroutine usando la funzione resume, inizia l'esecuzione e quando chiamiamo la funzione yield, sospende l'esecuzione. Anche in questo caso la stessa coroutine può continuare l'esecuzione con un'altra chiamata alla funzione di ripresa da dove era stata sospesa. Questo processo può continuare fino alla fine dell'esecuzione della coroutine.

Funzioni disponibili in Coroutines

La tabella seguente elenca tutte le funzioni disponibili per le coroutine in Lua e il loro utilizzo corrispondente.

Sr.No. Metodo e scopo
1

coroutine.create (f)

Crea una nuova coroutine con una funzione f e restituisce un oggetto di tipo "thread".

2

coroutine.resume (co [, val1, ...])

Riprende la coroutine co e passa i parametri se presenti. Restituisce lo stato dell'operazione e altri valori di ritorno opzionali.

3

coroutine.running ()

Restituisce la coroutine in esecuzione o nil se chiamato nel thread principale.

4

coroutine.status (co)

Restituisce uno dei valori in esecuzione, normale, sospeso o morto in base allo stato della coroutine.

5

coroutine.wrap (f)

Come coroutine.create, anche la funzione coroutine.wrap crea una coroutine, ma invece di restituire la coroutine stessa, restituisce una funzione che, quando chiamata, riprende la coroutine.

6

coroutine.yield (...)

Sospende la coroutine in esecuzione. Il parametro passato a questo metodo funge da valori di ritorno aggiuntivi per la funzione di ripresa.

Esempio

Facciamo un esempio per capire il concetto di coroutine.

co = coroutine.create(function (value1,value2)
   local tempvar3 = 10
   print("coroutine section 1", value1, value2, tempvar3)
	
   local tempvar1 = coroutine.yield(value1+1,value2+1)
   tempvar3 = tempvar3 + value1
   print("coroutine section 2",tempvar1 ,tempvar2, tempvar3)
	
   local tempvar1, tempvar2= coroutine.yield(value1+value2, value1-value2)
   tempvar3 = tempvar3 + value1
   print("coroutine section 3",tempvar1,tempvar2, tempvar3)
   return value2, "end"
	
end)

print("main", coroutine.resume(co, 3, 2))
print("main", coroutine.resume(co, 12,14))
print("main", coroutine.resume(co, 5, 6))
print("main", coroutine.resume(co, 10, 20))

Quando eseguiamo il programma sopra, otterremo il seguente output.

coroutine section 1	3	2	10
main	true	4	3
coroutine section 2	12	nil	13
main	true	5	1
coroutine section 3	5	6	16
main	true	2	end
main	false	cannot resume dead coroutine

Cosa fa l'esempio precedente?

Come accennato in precedenza, utilizziamo la funzione di ripresa per avviare l'operazione e la funzione di resa per interrompere l'operazione. Inoltre, puoi vedere che ci sono più valori di ritorno ricevuti dalla funzione di ripresa di coroutine.

  • Innanzitutto, creiamo una coroutine e la assegniamo a un nome di variabile co e la coroutine accetta due variabili come parametri.

  • Quando chiamiamo la prima funzione di ripresa, i valori 3 e 2 vengono mantenuti nelle variabili temporanee valore1 e valore2 fino alla fine della coroutine.

  • Per farti capire questo, abbiamo usato un tempvar3, che inizialmente è 10 e viene aggiornato a 13 e 16 dalle successive chiamate delle coroutine poiché value1 è mantenuto come 3 durante l'esecuzione della coroutine.

  • Il primo coroutine.yield restituisce due valori 4 e 3 alla funzione resume, che otteniamo aggiornando i parametri di input 3 e 2 nell'istruzione yield. Riceve anche lo stato vero / falso dell'esecuzione della coroutine.

  • Un altro aspetto delle coroutine è il modo in cui vengono gestiti i parametri successivi della chiamata di ripresa, nell'esempio sopra; puoi vedere che la variabile coroutine.yield riceve la chiamata successiva params che fornisce un modo potente per eseguire nuove operazioni con la conservazione dei valori param esistenti.

  • Infine, una volta che tutte le istruzioni nelle coroutine sono state eseguite, le chiamate successive restituiranno false e "non può riprendere la coroutine morta" come risposta.

Un altro esempio di coroutine

Guardiamo una semplice coroutine che restituisce un numero da 1 a 5 con l'aiuto della funzione di resa e della funzione di ripresa. Crea coroutine se non disponibile oppure riprende la coroutine esistente.

function getNumber()
   local function getNumberHelper()
      co = coroutine.create(function ()
      coroutine.yield(1)
      coroutine.yield(2)
      coroutine.yield(3)
      coroutine.yield(4)
      coroutine.yield(5)
      end)
      return co
   end
	
   if(numberHelper) then
      status, number = coroutine.resume(numberHelper);
		
      if coroutine.status(numberHelper) == "dead" then
         numberHelper = getNumberHelper()
         status, number = coroutine.resume(numberHelper);
      end
		
      return number
   else
      numberHelper = getNumberHelper()
      status, number = coroutine.resume(numberHelper);
      return number
   end
	
end

for index = 1, 10 do
   print(index, getNumber())
end

Quando eseguiamo il programma sopra, otterremo il seguente output.

1	1
2	2
3	3
4	4
5	5
6	1
7	2
8	3
9	4
10	5

C'è spesso un confronto di coroutine con i thread dei linguaggi multiprogrammazione, ma dobbiamo capire che le coroutine hanno caratteristiche simili di thread ma vengono eseguite solo una alla volta e non vengono mai eseguite contemporaneamente.

Controlliamo la sequenza di esecuzione del programma per soddisfare le esigenze con la fornitura di conservare alcune informazioni temporaneamente. L'utilizzo di variabili globali con le coroutine fornisce ancora più flessibilità alle coroutine.

La libreria I / O viene utilizzata per leggere e manipolare i file in Lua. Ci sono due tipi di operazioni sui file in Lua, ovvero descrittori di file impliciti e descrittori di file espliciti.

Per i seguenti esempi, useremo un file di esempio test.lua come mostrato di seguito.

-- sample test.lua
-- sample2 test.lua

Una semplice operazione di apertura di file utilizza la seguente istruzione.

file = io.open (filename [, mode])

Le varie modalità di file sono elencate nella tabella seguente.

Sr.No. Modalità e descrizione
1

"r"

Modalità di sola lettura ed è la modalità predefinita in cui viene aperto un file esistente.

2

"w"

Modalità abilitata alla scrittura che sovrascrive il file esistente o crea un nuovo file.

3

"a"

Modalità di aggiunta che apre un file esistente o crea un nuovo file da aggiungere.

4

"r+"

Modalità di lettura e scrittura per un file esistente.

5

"w+"

Tutti i dati esistenti vengono rimossi se il file esiste o viene creato un nuovo file con autorizzazioni di lettura e scrittura.

6

"a+"

Modalità di aggiunta con modalità di lettura abilitata che apre un file esistente o crea un nuovo file.

Descrittori di file impliciti

I descrittori di file impliciti utilizzano le modalità di input / output standard o utilizzano un singolo file di input e un singolo output. Di seguito è riportato un esempio di utilizzo di descrittori di file impliciti.

-- Opens a file in read
file = io.open("test.lua", "r")

-- sets the default input file as test.lua
io.input(file)

-- prints the first line of the file
print(io.read())

-- closes the open file
io.close(file)

-- Opens a file in append mode
file = io.open("test.lua", "a")

-- sets the default output file as test.lua
io.output(file)

-- appends a word test to the last line of the file
io.write("-- End of the test.lua file")

-- closes the open file
io.close(file)

Quando esegui il programma, otterrai un output della prima riga del file test.lua. Per il nostro programma, abbiamo ottenuto il seguente output.

-- Sample test.lua

Questa è stata la prima riga dell'istruzione nel file test.lua per noi. Anche la riga "- Fine del file test.lua" verrebbe aggiunta all'ultima riga del codice test.lua.

Nell'esempio sopra, puoi vedere come i descrittori impliciti funzionano con il file system usando i metodi io. "X". L'esempio precedente utilizza io.read () senza il parametro opzionale. Il parametro facoltativo può essere uno dei seguenti.

Sr.No. Modalità e descrizione
1

"*n"

Legge dalla posizione del file corrente e restituisce un numero se esiste nella posizione del file o restituisce zero.

2

"*a"

Restituisce tutto il contenuto del file dalla posizione del file corrente.

3

"*l"

Legge la riga dalla posizione del file corrente e sposta la posizione del file alla riga successiva.

4

number

Legge il numero di byte specificato nella funzione.

Altri metodi di I / O comuni includono,

  • io.tmpfile() - Restituisce un file temporaneo per la lettura e la scrittura che verrà rimosso una volta chiuso il programma.

  • io.type(file) - Restituisce se file, file chiuso o nil in base al file di input.

  • io.flush() - Cancella il buffer di output predefinito.

  • io.lines(optional file name)- Fornisce un iteratore di ciclo for generico che esegue il ciclo del file e alla fine chiude il file, nel caso in cui venga fornito il nome del file o il file predefinito venga utilizzato e non chiuso alla fine del ciclo.

Descrittori di file espliciti

Spesso utilizziamo un descrittore di file esplicito che ci consente di manipolare più file contemporaneamente. Queste funzioni sono abbastanza simili ai descrittori di file impliciti. Qui, usiamo file: nome_funzione invece di nome_io.funzione. Di seguito è riportato il seguente esempio della versione di file dello stesso esempio di descrittori di file impliciti.

-- Opens a file in read mode
file = io.open("test.lua", "r")

-- prints the first line of the file
print(file:read())

-- closes the opened file
file:close()

-- Opens a file in append mode
file = io.open("test.lua", "a")

-- appends a word test to the last line of the file
file:write("--test")

-- closes the open file
file:close()

Quando si esegue il programma, si otterrà un output simile all'esempio dei descrittori impliciti.

-- Sample test.lua

Tutte le modalità di apertura dei file e dei parametri di lettura per i descrittori esterni sono le stesse dei descrittori di file impliciti.

Altri metodi di file comuni includono,

  • file:seek(optional whence, optional offset)- Donde il parametro è "set", "cur" o "end". Imposta il nuovo puntatore del file con la posizione del file aggiornata dall'inizio del file. Gli offset sono in base zero in questa funzione. L'offset viene misurato dall'inizio del file se il primo argomento è "set"; dalla posizione corrente nel file se è "cur"; o dalla fine del file se è "end". I valori degli argomenti predefiniti sono "cur" e 0, quindi la posizione del file corrente può essere ottenuta chiamando questa funzione senza argomenti.

  • file:flush() - Cancella il buffer di output predefinito.

  • io.lines(optional file name)- Fornisce un iteratore di ciclo for generico che esegue il ciclo del file e alla fine chiude il file, nel caso in cui venga fornito il nome del file o il file predefinito venga utilizzato e non chiuso alla fine del ciclo.

Di seguito è mostrato un esempio per utilizzare il metodo seek. Sposta il cursore dalle 25 posizioni precedenti alla fine del file. La funzione di lettura stampa il resto del file dalla posizione di ricerca.

-- Opens a file in read
file = io.open("test.lua", "r")

file:seek("end",-25)
print(file:read("*a"))

-- closes the opened file
file:close()

Otterrai un output simile al seguente.

sample2 test.lua
--test

Puoi giocare con tutte le diverse modalità e parametri per conoscere la piena capacità delle operazioni sui file Lua.

Necessità di gestione degli errori

La gestione degli errori è piuttosto critica poiché le operazioni del mondo reale spesso richiedono l'uso di operazioni complesse, che includono operazioni sui file, transazioni di database e chiamate ai servizi web.

In qualsiasi programmazione è sempre richiesta la gestione degli errori. Gli errori possono essere di due tipi che includono,

  • Errori di sintassi
  • Errori di tempo di esecuzione

Errori di sintassi

Gli errori di sintassi si verificano a causa di un uso improprio di vari componenti del programma come operatori ed espressioni. Di seguito è riportato un semplice esempio di errore di sintassi.

a == 2

Come sapete, c'è una differenza tra l'uso di un singolo "uguale a" e del doppio "uguale a". L'utilizzo dell'uno al posto dell'altro può causare un errore. Un "uguale a" si riferisce all'assegnazione mentre un doppio "uguale a" si riferisce al confronto. Allo stesso modo, abbiamo espressioni e funzioni con modalità di implementazione predefinite.

Un altro esempio di errore di sintassi è mostrato di seguito:

for a= 1,10
   print(a)
end

Quando eseguiamo il programma sopra, otterremo il seguente output:

lua: test2.lua:2: 'do' expected near 'print'

Gli errori di sintassi sono molto più facili da gestire rispetto agli errori di runtime poiché l'interprete Lua individua l'errore in modo più chiaro rispetto al caso di errore di runtime. Dall'errore precedente, possiamo sapere facilmente che l'aggiunta di un'istruzione do prima dell'istruzione print è richiesta secondo la struttura Lua.

Errori in fase di esecuzione

In caso di errori di runtime, il programma viene eseguito correttamente, ma può causare errori di runtime dovuti a errori di input o funzioni mal gestite. Di seguito è mostrato un semplice esempio per mostrare l'errore di runtime.

function add(a,b)
   return a+b
end

add(10)

Quando creiamo il programma, verrà creato correttamente e verrà eseguito. Una volta eseguito, mostra un errore di runtime.

lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
	test2.lua:2: in function 'add'
	test2.lua:5: in main chunk
	[C]: ?

Questo è un errore di runtime, che si era verificato a causa del mancato passaggio di due variabili. Ilb parametro è previsto e qui è nullo e produce un errore.

Funzioni di asserzione ed errore

Per gestire gli errori, utilizziamo spesso due funzioni: assert e error. Di seguito viene mostrato un semplice esempio.

local function add(a,b)
   assert(type(a) == "number", "a is not a number")
   assert(type(b) == "number", "b is not a number")
   return a+b
end

add(10)

Quando eseguiamo il programma sopra, otterremo il seguente output di errore.

lua: test2.lua:3: b is not a number
stack traceback:
	[C]: in function 'assert'
	test2.lua:3: in function 'add'
	test2.lua:6: in main chunk
	[C]: ?

Il error (message [, level])termina l'ultima funzione protetta chiamata e restituisce il messaggio come messaggio di errore. Questo errore di funzione non ritorna mai. Di solito, l'errore aggiunge alcune informazioni sulla posizione dell'errore all'inizio del messaggio. L'argomento level specifica come ottenere la posizione dell'errore. Con il livello 1 (predefinito), la posizione dell'errore è quella in cui è stata chiamata la funzione di errore. Il livello 2 indica l'errore nel punto in cui è stata chiamata la funzione che ha chiamato l'errore; e così via. Il passaggio di un livello 0 evita l'aggiunta di informazioni sulla posizione di errore al messaggio.

pcall e xpcall

Nella programmazione Lua, per evitare di lanciare questi errori e di gestire errori, dobbiamo usare le funzioni pcall o xpcall.

Il pcall (f, arg1, ...)funzione chiama la funzione richiesta in modalità protetta. Se si verifica un errore nella funzione f, non viene generato un errore. Restituisce solo lo stato di errore. Di seguito è mostrato un semplice esempio di utilizzo di pcall.

function myfunction ()
   n = n/nil
end

if pcall(myfunction) then
   print("Success")
else
	print("Failure")
end

Quando eseguiamo il programma sopra, otterremo il seguente output.

Failure

Il xpcall (f, err)funzione chiama la funzione richiesta e imposta anche il gestore degli errori. Qualsiasi errore all'interno di f non viene propagato; invece, xpcall rileva l'errore, chiama la funzione err con l'oggetto errore originale e restituisce un codice di stato.

Di seguito è mostrato un semplice esempio per xpcall.

function myfunction ()
   n = n/nil
end

function myerrorhandler( err )
   print( "ERROR:", err )
end

status = xpcall( myfunction, myerrorhandler )
print( status)

Quando eseguiamo il programma sopra, otterremo il seguente output.

ERROR:	test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false

Come programmatore, è molto importante assicurarsi di occuparsi della corretta gestione degli errori nei programmi che scrivi. L'utilizzo della gestione degli errori può garantire che le condizioni impreviste oltre le condizioni limite vengano gestite senza disturbare l'utente del programma.

Lua fornisce una libreria di debug, che fornisce tutte le funzioni primitive per creare il nostro debugger. Anche se non esiste un debugger Lua integrato, abbiamo molti debugger per Lua, creati da vari sviluppatori e molti sono open source.

Le funzioni disponibili nella libreria di debug di Lua sono elencate nella tabella seguente insieme ai suoi usi.

Sr.No. Metodo e scopo
1

debug()

Entra in modalità interattiva per il debug, che rimane attivo fino a quando non digitiamo solo cont in una riga e premiamo invio. L'utente può ispezionare le variabili durante questa modalità utilizzando altre funzioni.

2

getfenv(object)

Restituisce l'ambiente dell'oggetto.

3

gethook(optional thread)

Restituisce le impostazioni di hook correnti del thread, come tre valori: la funzione di hook corrente, la maschera di hook corrente e il conteggio di hook corrente.

4

getinfo(optional thread, function or stack level, optional flag)

Restituisce una tabella con informazioni su una funzione. Puoi dare la funzione direttamente, oppure puoi dare un numero come valore di funzione, il che significa che la funzione in esecuzione a livello funzione dello stack di chiamate del thread dato - il livello 0 è la funzione corrente (getinfo stesso); il livello 1 è la funzione che ha chiamato getinfo; e così via. Se function è un numero maggiore del numero di funzioni attive, getinfo restituisce nil.

5

getlocal(optional thread, stack level, local index)

Restituisce il nome e il valore della variabile locale con indice locale della funzione a livello di stack. Restituisce nil se non è presente una variabile locale con l'indice dato e genera un errore quando viene chiamato con un livello fuori intervallo.

6

getmetatable(value)

Restituisce il metable dell'oggetto specificato o nil se non ha un metatable.

7

getregistry()

Restituisce la tabella del registro, una tabella predefinita che può essere utilizzata da qualsiasi codice C per memorizzare qualsiasi valore Lua che deve memorizzare.

8

getupvalue(function, upvalue index)

Questa funzione restituisce il nome e il valore dell'upvalue con indice superiore della funzione func. La funzione restituisce nil se non è presente alcun upvalue con l'indice specificato.

9

setfenv(function or thread or userdata, environment table)

Imposta l'ambiente dell'oggetto dato sulla tabella data. Restituisce oggetto.

10

sethook(optional thread, hook function, hook mask string with "c" and/or "r" and/or "l", optional instruction count)

Imposta la funzione data come hook. La maschera della stringa e il conteggio del numero descrivono quando verrà chiamato l'hook. Qui, c, r e l vengono chiamati ogni volta che Lua chiama, restituisce e inserisce ogni riga di codice in una funzione rispettivamente.

11

setlocal(optional thread, stack level, local index, value)

Assegna il valore alla variabile locale con indice locale della funzione a livello di stack. La funzione restituisce nil se non esiste una variabile locale con l'indice dato e genera un errore quando viene chiamata con un livello fuori intervallo. In caso contrario, restituisce il nome della variabile locale.

12

setmetatable(value, metatable)

Imposta la metatabile per l'oggetto dato sulla tabella data (che può essere nulla).

13

setupvalue(function, upvalue index, value)

Questa funzione assegna il valore all'upvalue con indice verso l'alto della funzione func. La funzione restituisce nil se non è presente alcun upvalue con l'indice specificato. In caso contrario, restituisce il nome dell'upvalue.

14

traceback(optional thread, optional message string, optional level argument)

Crea un messaggio di errore esteso con un traceback.

L'elenco sopra è l'elenco completo delle funzioni di debug in Lua e spesso utilizziamo una libreria che utilizza le funzioni precedenti e fornisce un debug più semplice. Usare queste funzioni e creare il nostro debugger è piuttosto complicato e non è preferibile. Comunque, vedremo un esempio di semplice utilizzo delle funzioni di debug.

function myfunction ()
   print(debug.traceback("Stack trace"))
   print(debug.getinfo(1))
   print("Stack trace end")

   return 10
end

myfunction ()
print(debug.getinfo(1))

Quando eseguiamo il programma sopra, otterremo la traccia dello stack come mostrato di seguito.

Stack trace
stack traceback:
	test2.lua:2: in function 'myfunction'
	test2.lua:8: in main chunk
	[C]: ?
table: 0054C6C8
Stack trace end

Nel programma di esempio precedente, la traccia dello stack viene stampata utilizzando la funzione debug.trace disponibile nella libreria di debug. Il debug.getinfo ottiene la tabella corrente della funzione.

Debug - Esempio

Spesso abbiamo bisogno di conoscere le variabili locali di una funzione per il debug. A tale scopo, possiamo usare getupvalue e per impostare queste variabili locali, usiamo setupvalue. Un semplice esempio per questo è mostrato di seguito.

function newCounter ()
   local n = 0
   local k = 0
	
   return function ()
      k = n
      n = n + 1
      return n
   end
	
end

counter = newCounter ()

print(counter())
print(counter())

local i = 1

repeat
   name, val = debug.getupvalue(counter, i)
	
   if name then
      print ("index", i, name, "=", val)
		
      if(name == "n") then
         debug.setupvalue (counter,2,10)
      end
		
      i = i + 1
   end -- if
	
until not name

print(counter())

Quando eseguiamo il programma sopra, otterremo il seguente output.

1
2
index	1	k	=	1
index	2	n	=	2
11

In questo esempio, il contatore si aggiorna di uno ogni volta che viene chiamato. Possiamo vedere lo stato corrente della variabile locale utilizzando la funzione getupvalue. Quindi impostiamo la variabile locale su un nuovo valore. Qui, n è 2 prima che venga chiamata l'operazione di impostazione. Usando la funzione setupvalue, viene aggiornato a 10. Ora, quando chiamiamo la funzione counter, restituirà 11 invece di 3.

Tipi di debug

  • Debug della riga di comando
  • Debug grafico

Debug della riga di comando

Il debug della riga di comando è il tipo di debug che utilizza la riga di comando per eseguire il debug con l'aiuto di comandi e istruzioni di stampa. Sono disponibili molti debugger della riga di comando per Lua di cui alcuni sono elencati di seguito.

  • RemDebug- RemDebug è un debugger remoto per Lua 5.0 e 5.1. Ti consente di controllare l'esecuzione di un altro programma Lua da remoto, impostando i punti di interruzione e ispezionando lo stato corrente del programma. RemDebug può anche eseguire il debug degli script CGILua.

  • clidebugger- Un semplice debugger dell'interfaccia della riga di comando per Lua 5.1 scritto in puro Lua. Non dipende da nient'altro che dalle librerie standard Lua 5.1. È stato ispirato da RemDebug ma non ha le sue strutture remote.

  • ctrace - Uno strumento per tracciare le chiamate API Lua.

  • xdbLua - Un semplice debugger della riga di comando Lua per la piattaforma Windows.

  • LuaInterface - Debugger- Questo progetto è un'estensione del debugger per LuaInterface. Porta l'interfaccia di debug Lua incorporata a un livello superiore. L'interazione con il debugger viene eseguita da eventi e chiamate al metodo.

  • Rldb- Questo è un debugger Lua remoto tramite socket, disponibile sia su Windows che su Linux. Può darti molte più funzionalità di qualsiasi altra esistente.

  • ModDebug - Ciò consente di controllare l'esecuzione di un altro programma Lua da remoto, impostare punti di interruzione e ispezionare lo stato corrente del programma.

Debug grafico

Il debug grafico è disponibile con l'aiuto di IDE in cui viene fornito il debug visivo di vari stati come valori di variabili, traccia dello stack e altre informazioni correlate. C'è una rappresentazione visiva e un controllo passo passo dell'esecuzione con l'aiuto di breakpoint, step into, step over e altri pulsanti nell'IDE.

Esistono numerosi debugger grafici per Lua e include quanto segue.

  • SciTE - L'IDE Windows predefinito per Lua fornisce più funzionalità di debug come breakpoint, step, step into, step over, watch variabili e così via.

  • Decoda - Questo è un debugger grafico con supporto per il debug remoto.

  • ZeroBrane Studio- IDE Lua con debugger remoto integrato, visualizzazione stack, visualizzazione Watch, console remota, analizzatore statico e altro ancora. Funziona con LuaJIT, Love2d, Moai e altri motori Lua; Windows, OSX e Linux. Open source.

  • akdebugger - Debugger ed editore plugin Lua per Eclipse.

  • luaedit - Presenta debug remoto, debug locale, evidenziazione della sintassi, elenco delle proposte di completamento, motore di proposizione dei parametri, gestione avanzata dei punti di interruzione (incluso il sistema delle condizioni sui punti di interruzione e il conteggio degli hit), elenco delle funzioni, elenco delle variabili globali e locali, orologi, gestione orientata alla soluzione.

Lua utilizza la gestione automatica della memoria che utilizza la garbage collection basata su determinati algoritmi incorporati in Lua. Come risultato della gestione automatica della memoria, come sviluppatore -

  • Non c'è bisogno di preoccuparsi dell'allocazione della memoria per gli oggetti.
  • Non c'è bisogno di liberarli quando non sono più necessari tranne che per impostarlo a zero.

Lua utilizza un garbage collector che viene eseguito di volta in volta per raccogliere oggetti morti quando non sono più accessibili dal programma Lua.

Tutti gli oggetti inclusi tabelle, dati utente, funzioni, thread, stringhe e così via sono soggetti alla gestione automatica della memoria. Lua utilizza un contrassegno incrementale e uno sweep collector che utilizza due numeri per controllare i suoi cicli di raccolta dei rifiutigarbage collector pause e garbage collector step multiplier. Questi valori sono in percentuale e il valore di 100 è spesso uguale a 1 internamente.

Pausa del Garbage Collector

La pausa del Garbage Collector viene utilizzata per controllare quanto tempo deve attendere il Garbage Collector, prima; viene richiamato di nuovo dalla gestione automatica della memoria di Lua. Valori inferiori a 100 significherebbero che Lua non aspetterà il ciclo successivo. Allo stesso modo, valori più alti di questo valore risulterebbero in un Garbage Collector lento e di natura meno aggressiva. Un valore di 200 significa che il collector attende che la memoria totale in uso raddoppi prima di iniziare un nuovo ciclo. Quindi, a seconda della natura e della velocità dell'applicazione, potrebbe essere necessario modificare questo valore per ottenere le migliori prestazioni nelle applicazioni Lua.

Moltiplicatore passo Garbage Collector

Questo moltiplicatore di passaggi controlla la velocità relativa del garbage collector rispetto a quella dell'allocazione della memoria nel programma Lua. Valori di passaggio più grandi porteranno al Garbage Collector più aggressivo e aumenteranno anche le dimensioni del passaggio di ogni passaggio incrementale di Garbage Collection. Valori inferiori a 100 potrebbero spesso portare ad evitare che il garbage collector non completi il ​​suo ciclo e non è generalmente preferito. Il valore predefinito è 200, il che significa che il Garbage Collector viene eseguito il doppio della velocità di allocazione della memoria.

Funzioni di Garbage Collector

Come sviluppatori, abbiamo un certo controllo sulla gestione automatica della memoria in Lua. Per questo, abbiamo i seguenti metodi.

  • collectgarbage("collect") - Esegue un ciclo completo di raccolta dei rifiuti.

  • collectgarbage("count") - Restituisce la quantità di memoria attualmente utilizzata dal programma in kilobyte.

  • collectgarbage("restart") - Se il Garbage Collector è stato arrestato, lo riavvia.

  • collectgarbage("setpause")- Imposta il valore dato come secondo parametro diviso per 100 nella variabile di pausa del Garbage Collector. I suoi usi sono discussi poco sopra.

  • collectgarbage("setstepmul")- Imposta il valore dato come secondo parametro diviso per 100 nella variabile del moltiplicatore del passo di spazzatura. I suoi usi sono discussi poco sopra.

  • collectgarbage("step")- Esegue un passaggio della raccolta dei rifiuti. Più grande è il secondo argomento, più grande sarà questo passaggio. Il collectgarbage restituirà true se il passaggio attivato è stato l'ultimo passaggio di un ciclo di raccolta dei rifiuti.

  • collectgarbage("stop") - Arresta il Garbage Collector se è in esecuzione.

Di seguito è mostrato un semplice esempio che utilizza l'esempio del garbage collector.

mytable = {"apple", "orange", "banana"}

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("collect"))

print(collectgarbage("count"))

Quando eseguiamo il programma sopra, otterremo il seguente output. Si noti che questo risultato varierà a causa della differenza nel tipo di sistema operativo e anche della funzione di gestione automatica della memoria di Lua.

23.1455078125   149
23.2880859375   295
0
22.37109375     380

Puoi vedere nel programma sopra, una volta che la raccolta dei rifiuti è terminata, ha ridotto la memoria utilizzata. Ma non è obbligatorio chiamarlo. Anche se non li chiamiamo, verrà eseguito automaticamente in una fase successiva dall'interprete Lua dopo il periodo predefinito.

Ovviamente, possiamo cambiare il comportamento del garbage collector usando queste funzioni se necessario. Queste funzioni forniscono allo sviluppatore un po 'di capacità aggiuntive per gestire situazioni complesse. A seconda del tipo di memoria necessaria per il programma, è possibile o meno utilizzare questa funzione. Ma è molto utile conoscere l'utilizzo della memoria nelle applicazioni e controllarlo durante la programmazione stessa per evitare risultati indesiderati dopo la distribuzione.

Introduzione a OOP

La programmazione orientata agli oggetti (OOP) è una delle tecniche di programmazione più utilizzate nell'era moderna della programmazione. Esistono numerosi linguaggi di programmazione che supportano l'OOP che includono,

  • C++
  • Java
  • Objective-C
  • Smalltalk
  • C#
  • Ruby

Caratteristiche di OOP

  • Class - Una classe è un modello estensibile per la creazione di oggetti, che fornisce valori iniziali per lo stato (variabili membro) e le implementazioni del comportamento.

  • Objects - È un'istanza di classe e ha una memoria separata allocata per se stessa.

  • Inheritance - È un concetto in base al quale le variabili e le funzioni di una classe vengono ereditate da un'altra classe.

  • Encapsulation- È il processo di combinazione dei dati e delle funzioni all'interno di una classe. È possibile accedere ai dati al di fuori della classe con l'aiuto delle funzioni. È anche noto come astrazione dei dati.

OOP a Lua

Puoi implementare l'orientamento agli oggetti in Lua con l'aiuto di tabelle e funzioni di prima classe di Lua. Inserendo funzioni e dati correlati in una tabella, viene formato un oggetto. L'ereditarietà può essere implementata con l'aiuto di metatables, fornendo un meccanismo di ricerca per funzioni (metodi) e campi inesistenti negli oggetti padre.

Le tabelle in Lua hanno le caratteristiche di un oggetto come lo stato e l'identità che è indipendente dai suoi valori. Due oggetti (tabelle) con lo stesso valore sono oggetti diversi, mentre un oggetto può avere valori diversi in momenti diversi, ma è sempre lo stesso oggetto. Come gli oggetti, le tabelle hanno un ciclo di vita indipendente da chi le ha create o da dove sono state create.

Un esempio del mondo reale

Il concetto di orientamento agli oggetti è ampiamente utilizzato ma è necessario comprenderlo chiaramente per ottenere un beneficio adeguato e massimo.

Consideriamo un semplice esempio di matematica. Spesso ci imbattiamo in situazioni in cui lavoriamo su forme diverse come cerchio, rettangolo e quadrato.

Le forme possono avere una proprietà comune Area. Quindi, possiamo estendere altre forme dalla forma dell'oggetto di base con l'area delle proprietà comuni. Ciascuna delle forme può avere le proprie proprietà e funzioni come un rettangolo può avere proprietà length, width, area come sue proprietà e printArea e calcolaArea come sue funzioni.

Creazione di una classe semplice

Di seguito viene mostrata una semplice implementazione di classe per un rettangolo con tre proprietà area, length e width. Ha anche una funzione printArea per stampare l'area calcolata.

-- Meta class
Rectangle = {area = 0, length = 0, breadth = 0}

-- Derived class method new

function Rectangle:new (o,length,breadth)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   self.length = length or 0
   self.breadth = breadth or 0
   self.area = length*breadth;
   return o
end

-- Derived class method printArea

function Rectangle:printArea ()
   print("The area of Rectangle is ",self.area)
end

Creazione di un oggetto

La creazione di un oggetto è il processo di allocazione della memoria per l'istanza della classe. Ciascuno degli oggetti ha la propria memoria e condivide i dati della classe comune.

r = Rectangle:new(nil,10,20)

Accesso alle proprietà

Possiamo accedere alle proprietà nella classe utilizzando l'operatore punto come mostrato di seguito -

print(r.length)

Accesso alla funzione membro

È possibile accedere a una funzione membro utilizzando l'operatore due punti con l'oggetto come mostrato di seguito:

r:printArea()

La memoria viene allocata e vengono impostati i valori iniziali. Il processo di inizializzazione può essere paragonato a costruttori in altri linguaggi orientati agli oggetti. Non è altro che una funzione che consente di impostare i valori come mostrato sopra.

Esempio completo

Vediamo un esempio completo usando l'orientamento agli oggetti in Lua.

-- Meta class
Shape = {area = 0}

-- Base class method new

function Shape:new (o,side)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   side = side or 0
   self.area = side*side;
   return o
end

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

-- Creating an object
myshape = Shape:new(nil,10)

myshape:printArea()

Quando esegui il programma sopra, otterrai il seguente output.

The area is 	100

Eredità in Lua

L'ereditarietà è il processo di estensione di oggetti di base semplici come la forma a rettangoli, quadrati e così via. Viene spesso utilizzato nel mondo reale per condividere ed estendere le proprietà e le funzioni di base.

Vediamo una semplice estensione di classe. Abbiamo una classe come mostrato di seguito.

-- Meta class
Shape = {area = 0}

-- Base class method new

function Shape:new (o,side)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   side = side or 0
   self.area = side*side;
   return o
end

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

Possiamo estendere la forma a una classe quadrata come mostrato di seguito.

Square = Shape:new()

-- Derived class method new

function Square:new (o,side)
   o = o or Shape:new(o,side)
   setmetatable(o, self)
   self.__index = self
   return o
end

Funzioni di base di over-riding

Possiamo sovrascrivere le funzioni della classe base che invece di utilizzare la funzione nella classe base, la classe derivata può avere la propria implementazione come mostrato di seguito -

-- Derived class method printArea

function Square:printArea ()
   print("The area of square is ",self.area)
end

Esempio completo di ereditarietà

Possiamo estendere la semplice implementazione della classe in Lua come mostrato sopra con l'aiuto di un altro nuovo metodo con l'aiuto dei metatables. Tutte le variabili membro e le funzioni della classe base vengono mantenute nella classe derivata.

-- Meta class
Shape = {area = 0}

-- Base class method new

function Shape:new (o,side)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   side = side or 0
   self.area = side*side;
   return o
end

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()

Square = Shape:new()

-- Derived class method new

function Square:new (o,side)
   o = o or Shape:new(o,side)
   setmetatable(o, self)
   self.__index = self
   return o
end

-- Derived class method printArea

function Square:printArea ()
   print("The area of square is ",self.area)
end

-- Creating an object
mysquare = Square:new(nil,10)
mysquare:printArea()

Rectangle = Shape:new()

-- Derived class method new

function Rectangle:new (o,length,breadth)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = length * breadth
   return o
end

-- Derived class method printArea

function Rectangle:printArea ()
    print("The area of Rectangle is ",self.area)
end

-- Creating an object

myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()

Quando eseguiamo il programma sopra, otterremo il seguente output:

The area is 	100
The area of square is 	100
The area of Rectangle is 	200

Nell'esempio precedente, abbiamo creato due classi derivate: Rectangle e Square dalla classe di base Square. È possibile sovrascrivere le funzioni della classe base nella classe derivata. In questo esempio, la classe derivata sovrascrive la funzione printArea.

Lua è un linguaggio altamente flessibile ed è spesso utilizzato su più piattaforme, comprese le applicazioni web. La comunità Kepler che è stata costituita nel 2004 per fornire componenti web open source in Lua.

Anche se sono stati sviluppati altri framework web che utilizzano Lua, ci concentreremo principalmente sui componenti forniti dalla comunità Kepler.

Applicazioni e framework

  • Orbit è un framework web MVC per Lua, basato su WSAPI.

  • WSAPI è l'API che astrae il server host web dalle applicazioni web Lua ed è la base per molti progetti.

  • Xavante è un server Web Lua che offre un'interfaccia WSAPI.

  • Sputnik è un wiki / CMS sviluppato su WSAPI su Kepler Project usato per umorismo e intrattenimento.

  • CGILuaoffre la creazione di pagine web LuaPages e LuaScripts, basate su WSAPI ma non più supportate. Usa invece Orbit, Sputnik o WSAPI.

In questo tutorial cercheremo di farti capire cosa può fare Lua e per saperne di più sulla sua installazione e utilizzo, fai riferimento a kepler sul sito

Orbita

Orbit è un framework web MVC per Lua. Abbandona completamente il modello CGILua degli "script" a favore delle applicazioni, dove ogni applicazione Orbit può stare in un unico file, ma puoi dividerla in più file se vuoi.

Tutte le applicazioni Orbit seguono il protocollo WSAPI, quindi attualmente funzionano con Xavante, CGI e Fastcgi. Include un programma di avvio che semplifica l'avvio di un'istanza Xavante per lo sviluppo.

Il modo più semplice per installare Orbit è usare LuaRocks. Luarocks install orbit è il comando per l'installazione. Per questo, devi prima installare LuaRocks .

Se non hai installato tutte le dipendenze, ecco i passaggi da seguire per configurare Orbit in ambiente Unix / Linux.

Installazione di Apache

Connettiti al tuo server. Installa Apache2, i suoi moduli di supporto e abilita i moduli Apache2 richiesti usando -

$ sudo apt-get install apache2 libapache2-mod-fcgid libfcgi-dev build-essential $ sudo a2enmod rewrite
$ sudo a2enmod fcgid $ sudo /etc/init.d/apache2 force-reload

Installa LuaRocks

$ sudo apt-get install luarocks

Installa WSAPI, FCGI, Orbit e Xavante

$ sudo luarocks install orbit
$ sudo luarocks install wsapi-xavante $ sudo luarocks install wsapi-fcgi

Configurazione di Apache2

$ sudo raj /etc/apache2/sites-available/default

Aggiungere la seguente sezione sotto la sezione <Directory / var / www /> del file di configurazione. Se questa sezione ha un "AllowOverride Nessuno", è necessario modificare "Nessuno" in "Tutto" in modo che il file .htaccess possa sovrascrivere la configurazione localmente.

<IfModule mod_fcgid.c>

   AddHandler fcgid-script .lua
   AddHandler fcgid-script .ws
   AddHandler fcgid-script .op
	
   FCGIWrapper "/usr/local/bin/wsapi.fcgi" .ws
   FCGIWrapper "/usr/local/bin/wsapi.fcgi" .lua
   FCGIWrapper "/usr/local/bin/op.fcgi" .op
	
   #FCGIServer "/usr/local/bin/wsapi.fcgi" -idle-timeout 60 -processes 1
   #IdleTimeout 60
   #ProcessLifeTime 60
	
</IfModule>

Riavviare il server per assicurarsi che le modifiche apportate abbiano effetto.

Per abilitare la tua applicazione, devi aggiungere + ExecCGI a un file .htaccess nella radice della tua applicazione Orbit - in questo caso, / var / www.

Options +ExecCGI
DirectoryIndex index.ws

Semplice esempio: orbita

#!/usr/bin/env index.lua

-- index.lua
require"orbit"

-- declaration
module("myorbit", package.seeall, orbit.new)

-- handler

function index(web)
   return my_home_page()
end

-- dispatch
myorbit:dispatch_get(index, "/", "/index")

-- Sample page

function my_home_page()

   return [[
      <head></head>
      <html>
         <h2>First Page</h2>
      </html>
   ]]
	
end

Ora dovresti essere in grado di avviare il tuo browser web. Vai a http: // localhost: 8080 / e dovresti vedere il seguente output:

First Page

Orbit fornisce un'altra opzione, cioè il codice Lua può generare html.

#!/usr/bin/env index.lua

-- index.lua
require"orbit"

function generate()
   return html {
      head{title "HTML Example"},
		
      body{
         h2{"Here we go again!"}
      }
   }
end

orbit.htmlify(generate)

print(generate())

Creazione di moduli

Di seguito è mostrato un semplice esempio di modulo:

#!/usr/bin/env index.lua
require"orbit"

function wrap (inner)
   return html{ head(), body(inner) }
end

function test ()
   return wrap(form (H'table' {
      tr{td"First name",td( input{type = 'text', name='first'})},
      tr{td"Second name",td(input{type = 'text', name='second'})},
      tr{ td(input{type = 'submit', value = 'Submit!'}),
         td(input{type = 'submit',value = 'Cancel'})
      },
   }))
end

orbit.htmlify(wrap,test)

print(test())

WSAPI

Come accennato in precedenza, WSAPI funge da base per molti progetti e dispone di più funzionalità incorporate. Puoi utilizzare WSAPI e supportare le seguenti piattaforme,

  • Windows
  • Sistemi basati su UNIX

I server e le interfacce supportati da WSAPI includono,

  • CGI
  • FastCGI
  • Xavante

WSAPI fornisce una serie di librerie, il che ci semplifica la programmazione web utilizzando Lua. Alcune delle funzionalità supportate in Lua includono,

  • Richiedi elaborazione
  • Buffering dell'output
  • Authentication
  • Caricamenti di file
  • Richiedi l'isolamento
  • Multiplexing

Di seguito è mostrato un semplice esempio di WSAPI:

#!/usr/bin/env wsapi.cgi

module(..., package.seeall)
function run(wsapi_env)
   local headers = { ["Content-type"] = "text/html" }
   
   local function hello_text()
      coroutine.yield("<html><body>")
      coroutine.yield("<p&gtHello Wsapi!</p>")
      coroutine.yield("<p&gtPATH_INFO: " .. wsapi_env.PATH_INFO .. "</p>")
      coroutine.yield("<p&gtSCRIPT_NAME: " .. wsapi_env.SCRIPT_NAME .. "</p>")
      coroutine.yield("</body></html>")
   end

   return 200, headers, coroutine.wrap(hello_text)
end

Puoi vedere nel codice sopra che viene formata e restituita una semplice pagina html. È possibile vedere l'utilizzo delle coroutine che consentono di restituire istruzione per istruzione alla funzione chiamante. Infine, vengono restituiti il ​​codice di stato html (200), le intestazioni e la pagina html.

Xavante

Xavante è un server Web Lua HTTP 1.1 che utilizza un'architettura modulare basata su gestori mappati URI. Xavante attualmente offre,

  • Gestore di file
  • Gestore di reindirizzamento
  • Gestore WSAPI

Il gestore di file viene utilizzato per i file generali. Il gestore di reindirizzamento abilita la rimappatura degli URI e il gestore WSAPI per la gestione con le applicazioni WSAPI.

Di seguito viene mostrato un semplice esempio.

require "xavante.filehandler"
require "xavante.cgiluahandler"
require "xavante.redirecthandler"

-- Define here where Xavante HTTP documents scripts are located
local webDir = XAVANTE_WEB

local simplerules = {

   { -- URI remapping example
      match = "^[^%./]*/$",
      with = xavante.redirecthandler,
      params = {"index.lp"}
   }, 

   { -- cgiluahandler example
      match = {"%.lp$", "%.lp/.*$", "%.lua$", "%.lua/.*$" },
      with = xavante.cgiluahandler.makeHandler (webDir)
   },
    
   { -- filehandler example
      match = ".",
      with = xavante.filehandler,
      params = {baseDir = webDir}
   },
} 

xavante.HTTP{
   server = {host = "*", port = 8080},
    
   defaultHost = {
      rules = simplerules
   },
}

Per utilizzare host virtuali con Xavante, la chiamata a xavante.HTTP verrebbe modificata in qualcosa di simile al seguente:

xavante.HTTP{
   server = {host = "*", port = 8080},
    
   defaultHost = {},
    
   virtualhosts = {
      ["www.sitename.com"] = simplerules
   }
}

Componenti Web Lua

  • Copas, un dispatcher basato su coroutine che può essere utilizzato dai server TCP / IP.

  • Cosmo, un motore di "modelli sicuri" che protegge la tua applicazione da codice arbitrario nei modelli.

  • Coxpcall incapsula pcall nativi di Lua e xpcall con quelli compatibili con coroutine.

  • LuaFileSystem, un modo portatile per accedere alla struttura della directory sottostante e agli attributi dei file.

  • Rings, una libreria che fornisce un modo per creare nuovi stati Lua dall'interno di Lua.

Nota finale

Ci sono così tanti framework e componenti web basati su Lua disponibili per noi e in base alle necessità, può essere scelto. Sono disponibili altri framework Web che includono quanto segue:

  • Moonstalkconsente lo sviluppo e l'hosting efficienti di progetti basati sul web generati dinamicamente realizzati con il linguaggio Lua; dalle pagine di base alle applicazioni complesse.

  • Lapis, un framework per la creazione di applicazioni web utilizzando MoonScript (o Lua) che gira all'interno di una versione personalizzata di Nginx chiamata OpenResty.

  • Lua Server Pages, un plug-in del motore di scripting Lua che elimina qualsiasi altro approccio allo sviluppo web incorporato, offre una scorciatoia drammatica alle tradizionali pagine del server C.

Questi framework web possono sfruttare le tue applicazioni web e aiutarti a svolgere potenti operazioni.

Per semplici operazioni sui dati, potremmo utilizzare i file, ma, a volte, queste operazioni sui file potrebbero non essere efficienti, scalabili e potenti. A tal fine, potremmo spesso passare all'utilizzo dei database. LuaSQL è una semplice interfaccia da Lua a numerosi sistemi di gestione di database. LuaSQL è la libreria, che fornisce supporto per diversi tipi di SQL. Questo include,

  • SQLite
  • Mysql
  • ODBC

In questo tutorial, tratteremo la gestione del database di MySQL e SQLite in Lua. Questo utilizza un'interfaccia generica per entrambi e dovrebbe essere possibile portare questa implementazione anche su altri tipi di database. Per prima cosa vediamo come puoi eseguire le operazioni in MySQL.

Configurazione db MySQL

Per poter utilizzare i seguenti esempi per funzionare come previsto, è necessaria la configurazione iniziale del database. Le ipotesi sono elencate di seguito.

  • Hai installato e configurato MySQL con l'utente predefinito come root e la password come "123456".

  • Hai creato un test del database.

  • Hai seguito il tutorial di MySQL per comprendere le basi di MySQL.

Importazione di MySQL

Possiamo usare un semplice require istruzione per importare la libreria sqlite assumendo che l'implementazione di Lua sia stata eseguita correttamente.

mysql = require "luasql.mysql"

La variabile mysql fornirà l'accesso alle funzioni facendo riferimento alla tabella principale di mysql.

Configurazione della connessione

Possiamo impostare la connessione avviando un ambiente MySQL e quindi creando una connessione per l'ambiente. È mostrato di seguito.

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')

La connessione sopra si connetterà a un file MySQL esistente e stabilirà la connessione con il file appena creato.

Esegui funzione

C'è una semplice funzione di esecuzione disponibile con la connessione che ci aiuterà a fare tutte le operazioni del db da creare, inserire, eliminare, aggiornare e così via. La sintassi è mostrata di seguito:

conn:execute([[ 'MySQLSTATEMENT' ]])

Nella sintassi precedente, dobbiamo assicurarci che la connessione sia aperta e la connessione MySQL esistente e sostituire 'MySQLSTATEMENT' con la dichiarazione corretta.

Crea esempio di tabella

Di seguito è mostrato un semplice esempio di creazione di una tabella. Crea una tabella con due parametri id di tipo integer e nome di tipo varchar.

mysql = require "luasql.mysql"

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')

print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]])
print(status,errorString )

Quando si esegue il programma precedente, verrà creata una tabella denominata sample con due colonne, ovvero id e name.

MySQL environment (004BB178)	MySQL connection (004BE3C8)
0	nil

In caso di errore, ti verrà restituita una dichiarazione di errore invece di zero. Di seguito viene mostrata una semplice dichiarazione di errore.

LuaSQL: Error executing query. MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"id INTEGER, name TEXT)' at line 1

Inserisci esempio di istruzione

Di seguito è mostrata un'istruzione di inserimento per MySQL.

conn:execute([[INSERT INTO sample values('11','Raj')]])

Esempio di istruzione di aggiornamento

Di seguito è mostrata una dichiarazione di aggiornamento per MySQL.

conn:execute([[UPDATE sample3 SET name='John' where id ='12']])

Elimina esempio di istruzione

Di seguito è mostrata un'istruzione di eliminazione per MySQL.

conn:execute([[DELETE from sample3 where id ='12']])

Seleziona Esempio di istruzione

Per quanto riguarda l'istruzione select, è necessario scorrere ciascuna delle righe ed estrarre i dati richiesti. Di seguito viene mostrata una semplice istruzione select.

cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   -- reusing the table of results
   row = cursor:fetch (row, "a")
end

Nel codice sopra, conn è una connessione MySQL aperta. Con l'aiuto del cursore restituito dall'istruzione execute, è possibile scorrere la risposta della tabella e recuperare i dati di selezione richiesti.

Un esempio completo

Di seguito viene fornito un esempio completo che include tutte le dichiarazioni di cui sopra.

mysql = require "luasql.mysql"

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]])
print(status,errorString )

status,errorString = conn:execute([[INSERT INTO sample3 values('12','Raj')]])
print(status,errorString )

cursor,errorString = conn:execute([[select * from sample3]])
print(cursor,errorString)

row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   row = cursor:fetch (row, "a")
end

-- close everything
cursor:close()
conn:close()
env:close()

Quando esegui il programma sopra, otterrai il seguente output.

MySQL environment (0037B178)	MySQL connection (0037EBA8)
0	nil
1	nil
MySQL cursor (003778A8)	nil
Id: 12, Name: Raj

Esecuzione di transazioni

Le transazioni sono un meccanismo che garantisce la coerenza dei dati. Le transazioni dovrebbero avere le seguenti quattro proprietà:

  • Atomicity - O una transazione viene completata o non accade nulla.

  • Consistency - Una transazione deve iniziare in uno stato coerente e lasciare il sistema in uno stato coerente.

  • Isolation - I risultati intermedi di una transazione non sono visibili al di fuori della transazione corrente.

  • Durability - Una volta che una transazione è stata confermata, gli effetti sono persistenti, anche dopo un errore di sistema.

La transazione inizia con START TRANSACTION; e termina con l'istruzione commit o rollback.

Avvia transazione

Per avviare una transazione, dobbiamo eseguire la seguente istruzione in Lua, supponendo che conn sia una connessione MySQL aperta.

conn:execute([[START TRANSACTION;]])

Transazione di rollback

È necessario eseguire la seguente istruzione per ripristinare le modifiche apportate dopo l'esecuzione della transazione di avvio.

conn:execute([[ROLLBACK;]])

Commit Transaction

È necessario eseguire la seguente istruzione per eseguire il commit delle modifiche apportate dopo l'esecuzione della transazione di avvio.

conn:execute([[COMMIT;]])

Abbiamo conosciuto MySQL nella sezione precedente e seguente spiega le operazioni SQL di base. Ricorda le transazioni, sebbene non sia spiegato di nuovo per SQLite3, ma le stesse istruzioni dovrebbero funzionare anche per SQLite3.

Importazione di SQLite

Possiamo usare una semplice istruzione require per importare la libreria SQLite assumendo che la tua implementazione di Lua sia stata eseguita correttamente. Durante l'installazione, una cartella libsql che contiene i file relativi al database.

sqlite3 = require "luasql.sqlite3"

La variabile sqlite3 fornirà l'accesso alle funzioni facendo riferimento alla tabella principale di sqlite3.

Configurazione della connessione

Possiamo impostare la connessione avviando un ambiente SQLite e quindi creando una connessione per l'ambiente. È mostrato di seguito.

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')

La connessione sopra si connetterà a un file SQLite esistente o creerà un nuovo file SQLite e stabilirà la connessione con il file appena creato.

Esegui funzione

C'è una semplice funzione di esecuzione disponibile con la connessione che ci aiuterà a fare tutte le operazioni del db da creare, inserire, eliminare, aggiornare e così via. La sintassi è mostrata di seguito:

conn:execute([[ 'SQLite3STATEMENT' ]])

Nella sintassi precedente dobbiamo assicurarci che conn sia aperta e che esista una connessione sqlite3 e sostituire "SQLite3STATEMENT" con l'istruzione corretta.

Crea esempio di tabella

Di seguito è mostrato un semplice esempio di creazione di una tabella. Crea una tabella con due parametri id di tipo integer e nome di tipo varchar.

sqlite3 = require "luasql.sqlite3"

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )

Quando si esegue il programma precedente, verrà creata una tabella denominata sample con due colonne, ovvero id e name.

SQLite3 environment (003EC918)	SQLite3 connection (00421F08)
0	nil

In caso di errore, ti verrà restituita una dichiarazione di errore invece di zero. Di seguito viene mostrata una semplice dichiarazione di errore.

LuaSQL: unrecognized token: ""'id' INTEGER, 'name' TEXT)"

Inserisci esempio di istruzione

Di seguito è mostrata un'istruzione di inserimento per SQLite.

conn:execute([[INSERT INTO sample values('11','Raj')]])

Seleziona Esempio di istruzione

Per quanto riguarda l'istruzione select, è necessario scorrere ciascuna delle righe ed estrarre i dati richiesti. Di seguito viene mostrata una semplice istruzione select.

cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   -- reusing the table of results
   row = cursor:fetch (row, "a")
end

Nel codice sopra, conn è una connessione sqlite3 aperta. Con l'aiuto del cursore restituito dall'istruzione execute, è possibile scorrere la risposta della tabella e recuperare i dati di selezione richiesti.

Un esempio completo

Di seguito viene fornito un esempio completo che include tutte le dichiarazioni di cui sopra.

sqlite3 = require "luasql.sqlite3"

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )

status,errorString = conn:execute([[INSERT INTO sample values('1','Raj')]])
print(status,errorString )

cursor,errorString = conn:execute([[select * from sample]])
print(cursor,errorString)

row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   row = cursor:fetch (row, "a")
end

-- close everything
cursor:close()
conn:close()
env:close()

Quando esegui il programma sopra, otterrai il seguente output.

SQLite3 environment (005EC918)	SQLite3 connection (005E77B0)
0	nil
1	nil
SQLite3 cursor (005E9200)	nil
Id: 1, Name: Raj

Possiamo eseguire tutte le query disponibili con l'aiuto di questa libreria libsql. Quindi, per favore, non fermarti con questi esempi. Sperimenta varie istruzioni di query disponibili nei rispettivi MySQL, SQLite3 e altri db supportati in Lua.

Lua è utilizzato in molti motori di gioco grazie alla sua semplice struttura del linguaggio e sintassi. La funzione di raccolta dei rifiuti è spesso molto utile nei giochi che consumano molta memoria a causa della ricca grafica utilizzata. Alcuni motori di gioco che utilizzano Lua includono:

  • Corona SDK
  • Gideros Mobile
  • ShiVa3D
  • Moai SDK
  • LOVE
  • CryEngine

Ciascuno di questi motori di gioco è basato su Lua e in ciascuno di questi motori è disponibile un ricco set di API. Esamineremo le capacità di ciascuno in breve.

Corona SDK

Corona SDK è un motore di gioco mobile multipiattaforma che supporta piattaforme iPhone, iPad e Android. Esiste una versione gratuita di Corona SDK che può essere utilizzata per piccoli giochi con funzionalità limitate. È possibile eseguire l'aggiornamento ad altre versioni quando necessario.

Corona SDK fornisce una serie di funzionalità che includono quanto segue:

  • API per la gestione della fisica e delle collisioni
  • API Web e di rete
  • API Game Network
  • API degli annunci
  • API di analisi
  • API di database e file system
  • API crittografiche e matematiche
  • API audio e multimediali

È più facile e veloce sviluppare un'applicazione utilizzando le API di cui sopra piuttosto che utilizzare le API native separatamente per iOS e Android.

Gideros Mobile

Gideros fornisce l'SDK multipiattaforma per creare giochi per iOS e Android. È gratuito da usare con uno splash made with Gideros. Alcuni degli straordinari vantaggi di Gideoros includono quanto segue:

  • Development IDE - Fornisce il proprio IDE che semplifica lo sviluppo di app Gideros.

  • Instant testing- Durante lo sviluppo del gioco, può essere testato su un dispositivo reale tramite Wifi in solo 1 secondo. Non è necessario sprecare tempo con un processo di esportazione o distribuzione.

  • Plugins- Puoi facilmente estendere il core con i plugin. Importa il tuo codice esistente (C, C ++, Java o Obj-C), collegalo a Lua e interpretalo direttamente. Decine di plugin open source sono già sviluppati e pronti per l'uso.

  • Clean OOP approach - Gideros fornisce il proprio sistema di classi con tutti gli standard OOP di base, consentendoti di scrivere codice pulito e riutilizzabile per qualsiasi tuo gioco futuro.

  • Native speed - Sviluppato su C / C ++ e OpenGL, il tuo gioco funziona a velocità nativa e utilizza appieno la potenza di CPU e GPU sottostanti.

ShiVa3D

ShiVa3D è uno dei motori di gioco 3D che fornisce un editor grafico progettato per creare applicazioni e videogiochi per Web, console e dispositivi mobili. Supporta più piattaforme che includono, Windows, Mac, Linux, iOS, Android, BlackBerry, Palm OS, Wii e WebOS.

Alcune delle caratteristiche principali includono

  • Plugin standard
  • API di modifica della mesh
  • IDE
  • Editor di terreno, oceano e animazione integrato
  • Supporto motore fisico ODE
  • Controllo completo delle mappe luminose
  • Anteprima dal vivo per materiali, particelle, tracce e HUD
  • Supporto per il formato di scambio Collada

L'edizione web di Shiva3d è completamente gratuita e le altre edizioni sono iscritte.

Moai SDK

Moai SDK è un motore di gioco mobile multipiattaforma che supporta piattaforme iPhone, iPad e Android. La piattaforma Moai inizialmente consisteva in Moai SDK, un motore di gioco open source, e Moai Cloud, una piattaforma cloud come servizio per l'hosting e la distribuzione di servizi di gioco. Ora il Moai Cloud è spento e solo il motore di gioco è disponibile.

Moai SDK funziona su più piattaforme tra cui iOS, Android, Chrome, Windows, Mac e Linux.

AMORE

LOVE è un framework che puoi usare per creare giochi 2D. È gratuito e open-source. Supporta piattaforme Windows, Mac OS X e Linux.

Fornisce molteplici funzionalità che includono,

  • API audio
  • API del file system
  • API per tastiera e joystick
  • API matematica
  • API per finestre e mouse
  • API fisica
  • API di sistema e timer

CryEngine

CryEngine è un motore di gioco sviluppato dallo sviluppatore di giochi tedesco Crytek. Si è evoluto dalla generazione 1 alla generazione 4 ed è una soluzione di sviluppo avanzata. Supporta giochi per PC, Xbox 360, PlayStation3 e WiiU.

Fornisce molteplici funzionalità che includono,

  • Effetti visivi come illuminazione naturale e ombre morbide dinamiche, illuminazione globale dinamica in tempo reale, volume di propagazione della luce, ombreggiatura delle particelle, tassellatura e così via.

  • Sistema di animazione del personaggio e sistema di individualizzazione del personaggio.

  • Animazione scheletrica parametrica e editor di animazione facciale dedicato unico

  • Sistemi di intelligenza artificiale come mesh di navigazione multistrato e sistema di punti tattici. Fornisce anche un sistema di modifica AI di facile progettazione.

  • In Game Mixing & Profiling, Sistema audio basato sui dati Suoni dinamici e musica interattiva e così via.

  • Funzionalità fisiche come Deformazione procedurale e Fisica avanzata delle funi.

Una nota finale

Ciascuno di questi SDK / framework di gioco ha i propri vantaggi e svantaggi. Una scelta corretta tra di loro semplifica il tuo compito e puoi divertirti meglio. Quindi, prima di usarlo, devi conoscere i requisiti per il tuo gioco e quindi analizzare quale soddisfa tutte le tue esigenze e quindi dovresti usarli.

Le librerie standard Lua forniscono un ricco set di funzioni che viene implementato direttamente con l'API C ed è integrato con il linguaggio di programmazione Lua. Queste librerie forniscono servizi all'interno del linguaggio di programmazione Lua e anche servizi esterni come operazioni su file e db.

Queste librerie standard integrate nell'API C ufficiale sono fornite come moduli C separati. Include quanto segue:

  • Libreria di base, che include la sotto-libreria coroutine
  • Libreria moduli
  • Manipolazione delle stringhe
  • Manipolazione della tabella
  • Libreria matematica
  • Input e output di file
  • Strutture del sistema operativo
  • Strutture di debug

Libreria di base

Abbiamo utilizzato la libreria di base durante il tutorial sotto vari argomenti. La tabella seguente fornisce collegamenti alle pagine correlate ed elenca le funzioni trattate in varie parti di questo tutorial Lua.

Sr.No. Libreria / Metodo e scopo
1

Error Handling

Include funzioni di gestione degli errori come asserzione, errore come spiegato in Lua - Gestione degli errori .

2

Memory Management

Include le funzioni di gestione automatica della memoria relative alla garbage collection come spiegato in Lua - Garbage Collection .

3

dofile ([filename])

Apre il file ed esegue il contenuto del file come un blocco. Se non viene passato alcun parametro, questa funzione esegue il contenuto dell'input standard. Gli errori verranno propagati al chiamante.

4

_G

Quindi è la variabile globale che contiene l'ambiente globale (ovvero, _G._G = _G). Lua stesso non utilizza questa variabile.

5

getfenv ([f])

Restituisce l'ambiente corrente utilizzato dalla funzione. f può essere una funzione Lua o un numero che specifica la funzione a quel livello di stack - Il livello 1 è la funzione che chiama getfenv. Se la funzione data non è una funzione Lua, o se f è 0, getfenv restituisce l'ambiente globale. L'impostazione predefinita per f è 1.

6

getmetatable (object)

Se l'oggetto non ha un metable, restituisce nil. Altrimenti, se il metatable dell'oggetto ha un campo "__metatable", restituisce il valore associato. In caso contrario, restituisce la metatabile dell'oggetto specificato.

7

ipairs (t)

Questa funzione recupera gli indici e i valori delle tabelle.

8

load (func [, chunkname])

Carica un pezzo usando la funzione func per ottenere i suoi pezzi. Ogni chiamata a func deve restituire una stringa che si concatena con i risultati precedenti.

9

loadfile ([filename]))

Simile a load, ma ottiene il blocco dal file filename o dallo standard input, se non viene fornito alcun nome file.

10

loadstring (string [, chunkname])

Simile a load, ma ottiene il blocco dalla stringa data.

11

next (table [, index])

Consente a un programma di attraversare tutti i campi di una tabella. Il suo primo argomento è una tabella e il suo secondo argomento è un indice in questa tabella. next restituisce l'indice successivo della tabella e il valore associato.

12

pairs (t)

Sospende la coroutine in esecuzione. Il parametro passato a questo metodo funge da valori di ritorno aggiuntivi per la funzione di ripresa.

13

print (...)

Sospende la coroutine in esecuzione. Il parametro passato a questo metodo funge da valori di ritorno aggiuntivi per la funzione di ripresa.

14

rawequal (v1, v2)

Verifica se v1 è uguale a v2, senza richiamare alcun metametodo. Restituisce un valore booleano.

15

rawget (table, index)

Ottiene il valore reale di table [index], senza richiamare alcun metametodo. il tavolo deve essere un tavolo; index può essere qualsiasi valore.

16

rawset (table, index, value)

Imposta il valore reale di table [index] su value, senza richiamare alcun metametodo. table deve essere una tabella, indicizzare qualsiasi valore diverso da zero e valutare qualsiasi valore Lua. Questa funzione restituisce table.

17

select (index, ...)

Se index è un numero, restituisce tutti gli argomenti dopo il numero di argomento index. In caso contrario, index deve essere la stringa "#" e select restituisce il numero totale di argomenti aggiuntivi ricevuti.

18

setfenv (f, table)

Imposta l'ambiente che deve essere utilizzato dalla funzione data. f può essere una funzione Lua o un numero che specifica la funzione a quel livello di stack - Il livello 1 è la funzione che chiama setfenv. setfenv restituisce la funzione data. Come caso speciale, quando f è 0 setfenv cambia l'ambiente del thread in esecuzione. In questo caso, setfenv non restituisce valori.

19

setmetatable (table, metatable)

Imposta il metatable per la tabella data. (Non è possibile modificare il metatable di altri tipi da Lua, solo da C.) Se metatable è nullo, rimuove il metatable della tabella data. Se il metatable originale ha un campo "__metatable", genera un errore. Questa funzione restituisce table.

20

tonumber (e [, base])

Prova a convertire il suo argomento in un numero. Se l'argomento è già un numero o una stringa convertibile in un numero, tonumber restituisce questo numero; in caso contrario, restituisce zero.

21

tostring (e)

Riceve un argomento di qualsiasi tipo e lo converte in una stringa in un formato ragionevole. Per il controllo completo di come vengono convertiti i numeri, utilizzare string.format.

22

type (v)

Restituisce il tipo del suo unico argomento, codificato come una stringa. I possibili risultati di questa funzione sono "nil" (una stringa, non il valore nil), "number", "string", "boolean", "table", "function", "thread" e "userdata".

23

unpack (list [, i [, j]])

Restituisce gli elementi dalla tabella data.

24

_VERSION

Una variabile globale (non una funzione) che contiene una stringa contenente la versione corrente dell'interprete. Il contenuto corrente di questa variabile è "Lua 5.1".

25

Coroutines

Include le funzioni di manipolazione della coroutine come spiegato in Lua - Coroutines .

Libreria dei moduli

La libreria dei moduli fornisce le funzioni di base per caricare i moduli in Lua. Esporta una funzione direttamente nell'ambiente globale: require. Tutto il resto viene esportato in un pacchetto di tabelle. I dettagli sulla libreria dei moduli sono spiegati nel capitolo precedente Lua - Tutorial sui moduli .

Manipolazione delle stringhe

Lua fornisce un ricco set di funzioni di manipolazione delle stringhe. Il precedente tutorial Lua - Strings lo copre in dettaglio.

Manipolazione della tabella

Lua dipende dalle tabelle in quasi tutte le sue operazioni. Il precedente tutorial Lua - Tabelle lo copre in dettaglio.

Input e output di file

Spesso abbiamo bisogno di una struttura di memorizzazione dei dati nella programmazione e questa è fornita dalle funzioni di libreria standard per I / O di file in Lua. È discusso nel precedente tutorial Lua - File I / O.

Strutture di debug

Lua fornisce una libreria di debug che fornisce tutte le funzioni primitive per noi per creare il nostro debugger. È discusso in Lua precedente - Esercitazione sul debug .

Spesso abbiamo bisogno di operazioni matematiche nei calcoli scientifici e ingegneristici e possiamo avvalerci di questo utilizzando la matematica della libreria Lua standard. L'elenco delle funzioni disponibili nella libreria matematica è mostrato nella tabella seguente.

Sr.No. Libreria / Metodo e scopo
1

math.abs (x)

Restituisce il valore assoluto di x.

2

math.acos (x)

Restituisce l'arcocoseno di x (in radianti).

3

math.asin (x)

Restituisce l'arcoseno di x (in radianti).

4

math.atan (x)

Restituisce l'arcotangente di x (in radianti).

5

math.atan2 (y, x)

Restituisce l'arcotangente di y / x (in radianti), ma utilizza i segni di entrambi i parametri per trovare il quadrante del risultato. (Gestisce correttamente anche il caso in cui x è zero.)

6

math.ceil (x)

Restituisce il numero intero più piccolo maggiore o uguale a x.

7

math.cos (x)

Restituisce il coseno di x (assunto in radianti).

8

math.cosh (x)

Restituisce il coseno iperbolico di x.

9

math.deg (x)

Restituisce l'angolo x (espresso in radianti) in gradi.

10

math.exp (x)

Restituisce il valore e potenza x.

11

math.floor (x)

Restituisce il numero intero più grande minore o uguale a x.

12

math.fmod (x, y)

Restituisce il resto della divisione di x per y che arrotonda il quoziente verso zero.

13

math.frexp (x)

Restituisce m ed e tali che x = m2e, e è un numero intero e il valore assoluto di m è compreso nell'intervallo [0,5, 1) (o zero quando x è zero).

14

math.huge

Il valore HUGE_VAL, un valore maggiore o uguale a qualsiasi altro valore numerico.

15

math.ldexp (m, e)

Restituisce m2e (e dovrebbe essere un numero intero).

16

math.log (x)

Restituisce il logaritmo naturale di x.

17

math.log10 (x)

Restituisce il logaritmo in base 10 di x.

18

math.max (x, ...)

Restituisce il valore massimo tra i suoi argomenti.

19

math.min (x, ...)

Restituisce il valore minimo tra i suoi argomenti.

20

math.modf (x)

Restituisce due numeri, la parte integrale di x e la parte frazionaria di x.

21

math.pi

Il valore di pi greco.

22

math.pow (x, y)

Restituisce xy. (Puoi anche usare l'espressione x ^ y per calcolare questo valore.)

23

math.rad (x)

Restituisce l'angolo x (espresso in gradi) in radianti.

24

math.random ([m [, n]])

Questa funzione è un'interfaccia alla semplice funzione generatore pseudocasuale rand fornita da ANSI C.Quando viene chiamata senza argomenti, restituisce un numero reale pseudocasuale uniforme compreso nell'intervallo [0,1). Quando viene chiamato con un numero intero m, math.random restituisce un numero intero pseudo-casuale uniforme nell'intervallo [1, m]. Quando viene chiamato con due numeri interi m e n, math.random restituisce un intero pseudo-casuale uniforme nell'intervallo [m, n].

25

math.randomseed (x)

Imposta x come "seme" per il generatore pseudo-casuale: semi uguali producono sequenze di numeri uguali.

26

math.sin (x)

Restituisce il seno di x (assunto in radianti).

27

math.sinh (x)

Restituisce il seno iperbolico di x.

28

math.sqrt (x)

Restituisce la radice quadrata di x. (Puoi anche usare l'espressione x ^ 0,5 per calcolare questo valore.)

29

math.tan (x)

Restituisce la tangente di x (si presume che sia in radianti).

30

math.tanh (x)

Restituisce la tangente iperbolica di x.

Funzioni trigonometriche

Di seguito è mostrato un semplice esempio di utilizzo della funzione trigonometrica.

radianVal = math.rad(math.pi / 2)

io.write(radianVal,"\n")

-- Sin value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.sin(radianVal)),"\n")

-- Cos value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.cos(radianVal)),"\n")

-- Tan value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.tan(radianVal)),"\n")

-- Cosh value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.cosh(radianVal)),"\n")

-- Pi Value in degrees
io.write(math.deg(math.pi),"\n")

Quando eseguiamo il programma sopra, otterremo il seguente output.

0.027415567780804
0.0 
1.0 
0.0 
1.0 
180

Altre funzioni matematiche comuni

Di seguito viene mostrato un semplice esempio di utilizzo delle funzioni matematiche comuni.

-- Floor
io.write("Floor of 10.5055 is ", math.floor(10.5055),"\n")

-- Ceil
io.write("Ceil of 10.5055 is ", math.ceil(10.5055),"\n")

-- Square root
io.write("Square root of 16 is ",math.sqrt(16),"\n")

-- Power
io.write("10 power 2 is ",math.pow(10,2),"\n")
io.write("100 power 0.5 is ",math.pow(100,0.5),"\n")

-- Absolute
io.write("Absolute value of -10 is ",math.abs(-10),"\n")

--Random
math.randomseed(os.time())
io.write("Random number between 1 and 100 is ",math.random(),"\n")

--Random between 1 to 100
io.write("Random number between 1 and 100 is ",math.random(1,100),"\n")

--Max
io.write("Maximum in the input array is ",math.max(1,100,101,99,999),"\n")

--Min
io.write("Minimum in the input array is ",math.min(1,100,101,99,999),"\n")

Quando eseguiamo il programma sopra, otterremo il seguente output.

Floor of 10.5055 is 10
Ceil of 10.5055 is 11
Square root of 16 is 4
10 power 2 is 100
100 power 0.5 is 10
Absolute value of -10 is 10
Random number between 1 and 100 is 0.22876674703207
Random number between 1 and 100 is 7
Maximum in the input array is 999
Minimum in the input array is 1

Gli esempi sopra sono solo alcuni degli esempi comuni, possiamo usare la libreria matematica in base alle nostre necessità, quindi prova a usare tutte le funzioni per essere più familiare.

In qualsiasi applicazione, è spesso richiesto per accedere alle funzioni a livello di sistema operativo ed è reso disponibile con la libreria del sistema operativo. L'elenco delle funzioni disponibili è elencato nella tabella seguente.

Sr.No. Libreria / Metodo e scopo
1

os.clock ()

Restituisce un'approssimazione della quantità in secondi di tempo della CPU utilizzata dal programma.

2

os.date ([format [, time]])

Restituisce una stringa o una tabella contenente data e ora, formattata in base al formato di stringa specificato.

3

os.difftime (t2, t1)

Restituisce il numero di secondi dall'ora t1 all'ora t2. In POSIX, Windows e alcuni altri sistemi, questo valore è esattamente t2-t1.

4

os.execute ([command])

Questa funzione è equivalente al sistema di funzioni ANSI C. Passa il comando per essere eseguito da una shell del sistema operativo. Il suo primo risultato è vero se il comando è terminato correttamente o nullo in caso contrario.

5

os.exit ([code [, close])

Chiama l'uscita della funzione ANSI C per terminare il programma host. Se il codice è vero, lo stato restituito è EXIT_SUCCESS; se il codice è falso, lo stato restituito è EXIT_FAILURE; se il codice è un numero, lo stato restituito è questo numero.

6

os.getenv (varname)

Restituisce il valore della variabile di ambiente del processo varname o nil se la variabile non è definita.

7

os.remove (filename)

Elimina il file (o la directory vuota, sui sistemi POSIX) con il nome specificato. Se questa funzione fallisce, restituisce zero, più una stringa che descrive l'errore e il codice di errore.

8

os.rename (oldname, newname)

Rinomina il file o la directory denominata oldname in newname. Se questa funzione fallisce, restituisce zero, più una stringa che descrive l'errore e il codice di errore.

9

os.setlocale (locale [, category])

Imposta la locale corrente del programma. locale è una stringa dipendente dal sistema che specifica una locale; categoria è una stringa opzionale che descrive la categoria da modificare: "all", "collate", "ctype", "money", "numeric" o "time"; la categoria predefinita è "all". La funzione restituisce il nome della nuova locale o nullo se la richiesta non può essere soddisfatta.

10

os.time ([table])

Restituisce l'ora corrente quando viene chiamata senza argomenti o un'ora che rappresenta la data e l'ora specificate dalla tabella data. Questa tabella deve contenere i campi anno, mese e giorno e i campi ora (il valore predefinito è 12), min (il valore predefinito è 0), sec (il valore predefinito è 0) e isdst (il valore predefinito è nullo). Per una descrizione di questi campi, vedere la funzione os.date.

11

os.tmpname ()

Restituisce una stringa con un nome file che può essere utilizzato per un file temporaneo. Il file deve essere aperto esplicitamente prima del suo utilizzo e rimosso esplicitamente quando non è più necessario.

Funzioni comuni del sistema operativo

Di seguito viene mostrato un semplice esempio di utilizzo delle funzioni matematiche comuni.

-- Date with format
io.write("The date is ", os.date("%m/%d/%Y"),"\n")

-- Date and time
io.write("The date and time is ", os.date(),"\n")

-- Time
io.write("The OS time is ", os.time(),"\n")

-- Wait for some time
for i=1,1000000 do
end

-- Time since Lua started
io.write("Lua started before ", os.clock(),"\n")

Quando eseguiamo il programma precedente, otterremo un output simile al seguente.

The date is 01/25/2014
The date and time is 01/25/14 07:38:40
The OS time is 1390615720
Lua started before 0.013

Gli esempi sopra sono solo alcuni degli esempi comuni, possiamo usare la libreria del sistema operativo in base alle nostre necessità, quindi prova a utilizzare tutte le funzioni per essere più familiare. Esistono funzioni come remove che aiuta a rimuovere il file, execute che ci aiuta a eseguire i comandi del sistema operativo come spiegato sopra.