Lua - Guide rapide

Lua est un langage de programmation extensible et léger écrit en C. Il a commencé comme un projet interne en 1993 par Roberto Ierusalimschy, Luiz Henrique de Figueiredo et Waldemar Celes.

Il a été conçu dès le début pour être un logiciel qui peut être intégré au code écrit en C et dans d'autres langages conventionnels. Cette intégration apporte de nombreux avantages. Il n'essaie pas de faire ce que C peut déjà faire mais vise à offrir ce pour quoi C n'est pas bon: une bonne distance du matériel, des structures dynamiques, aucune redondance, une facilité de test et de débogage. Pour cela, Lua dispose d'un environnement sûr, d'une gestion automatique de la mémoire et de bonnes fonctionnalités pour gérer les chaînes et autres types de données de taille dynamique.

traits

Lua fournit un ensemble de fonctionnalités uniques qui le distingue des autres langues. Ceux-ci comprennent -

  • Extensible
  • Simple
  • Efficient
  • Portable
  • Gratuit et ouvert

Exemple de code

print("Hello World!")

Comment Lua est-il implémenté?

Lua se compose de deux parties - la partie interpréteur Lua et le système logiciel fonctionnel. Le système logiciel qui fonctionne est une application informatique réelle qui peut interpréter des programmes écrits dans le langage de programmation Lua. L'interpréteur Lua est écrit en ANSI C, il est donc hautement portable et peut fonctionner sur un large éventail d'appareils, des serveurs de réseau haut de gamme aux petits appareils.

La langue de Lua et son interprète sont matures, petites et rapides. Il a évolué à partir d'autres langages de programmation et des meilleurs standards logiciels. Être de petite taille lui permet de fonctionner sur de petits appareils avec une faible mémoire.

Apprendre Lua

Le point le plus important lors de l'apprentissage de Lua est de se concentrer sur les concepts sans se perdre dans ses détails techniques.

Le but de l'apprentissage d'un langage de programmation est de devenir un meilleur programmeur; c'est-à-dire devenir plus efficace dans la conception et la mise en œuvre de nouveaux systèmes et dans la maintenance des anciens.

Quelques utilisations de Lua

  • Programmation de jeux

  • Script dans les applications autonomes

  • Script sur le Web

  • Extensions et modules complémentaires pour les bases de données telles que MySQL Proxy et MySQL WorkBench

  • Les systèmes de sécurité comme le système de détection d'intrusion.

Configuration de l'environnement local

Si vous souhaitez toujours configurer votre environnement pour le langage de programmation Lua, vous avez besoin des logiciels suivants disponibles sur votre ordinateur - (a) Text Editor, (b) The Lua Interpreter, et (c) Lua Compiler.

Éditeur de texte

Vous avez besoin d'un éditeur de texte pour saisir votre programme. Quelques exemples d'éditeurs incluent le Bloc-notes Windows, la commande d'édition du système d'exploitation, Brief, Epsilon, EMACS et vim ou vi.

Le nom et la version de l'éditeur de texte peuvent varier selon les systèmes d'exploitation. Par exemple, le Bloc-notes sera utilisé sous Windows, et vim ou vi pourra être utilisé sous Windows ainsi que Linux ou UNIX.

Les fichiers que vous créez avec votre éditeur sont appelés fichiers source et ces fichiers contiennent le code source du programme. Les fichiers source des programmes Lua sont généralement nommés avec l'extension".lua".

L'interprète Lua

C'est juste un petit programme qui vous permet de taper des commandes Lua et de les exécuter immédiatement. Il arrête l'exécution d'un fichier Lua au cas où il rencontrerait une erreur contrairement à un compilateur qui s'exécute complètement.

Le compilateur Lua

Lorsque nous étendons Lua à d'autres langages / applications, nous avons besoin d'un kit de développement logiciel avec un compilateur compatible avec l'interface de programme d'application Lua.

Installation sous Windows

Il existe un IDE distinct nommé "SciTE" développé pour l'environnement Windows, qui peut être téléchargé à partir de https://code.google.com/p/luaforwindows/ section de téléchargement.

Exécutez l'exécutable téléchargé pour installer Lua IDE.

Puisqu'il s'agit d'un IDE, vous pouvez à la fois créer et construire le code Lua en utilisant le même.

Au cas où vous souhaiteriez installer Lua en mode ligne de commande, vous devez installer MinGW ou Cygwin, puis compiler et installer Lua dans Windows.

Installation sous Linux

Pour télécharger et construire Lua, utilisez la commande suivante -

$ 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

Afin d'installer sur d'autres plates-formes comme aix, ansi, bsd, Linux générique, mingw, posix, solaris en remplaçant Linux dans make Linux, testez avec le nom de plate-forme correspondant.

Nous avons un helloWorld.lua, en Lua comme suit -

print("Hello World!")

Maintenant, nous pouvons créer et exécuter un fichier Lua, dit helloWorld.lua, en basculant vers le dossier contenant le fichier à l'aide de cd, puis en utilisant la commande suivante -

$ lua helloWorld

Nous pouvons voir la sortie suivante.

Hello World!

Installation sous Mac OS X

Pour construire / tester Lua sous Mac OS X, utilisez la commande suivante -

$ 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

Dans certains cas, vous n'avez peut-être pas installé les outils Xcode et de ligne de commande. Dans de tels cas, vous ne pourrez pas utiliser la commande make. Installez Xcode depuis le Mac App Store. Ensuite, allez dans Préférences de Xcode, puis passez à Téléchargements et installez le composant nommé "Outils de ligne de commande". Une fois le processus terminé, la commande make sera disponible.

Il n'est pas obligatoire pour vous d'exécuter l'instruction "make macosx test". Même sans exécuter cette commande, vous pouvez toujours utiliser Lua sous Mac OS X.

Nous avons un helloWorld.lua, en Lua, comme suit -

print("Hello World!")

Maintenant, nous pouvons créer et exécuter un fichier Lua, disons helloWorld.lua, en basculant vers le dossier contenant le fichier à l'aide de cd, puis en utilisant la commande suivante -

$ lua helloWorld

Nous pouvons voir la sortie suivante -

Hello World!

IDE Lua

Comme mentionné précédemment, pour Windows SciTE, Lua IDE est l'IDE par défaut fourni par l'équipe de création de Lua. L'EDI alternatif disponible provient de ZeroBrane Studio, qui est disponible sur plusieurs plates-formes telles que Windows, Mac et Linux.

Il existe également des plugins pour eclipse qui permettent le développement de Lua. L'utilisation de l'EDI facilite le développement avec des fonctionnalités telles que la complétion de code et est fortement recommandée. L'EDI fournit également une programmation en mode interactif similaire à la version en ligne de commande de Lua.

Commençons à créer notre premier programme Lua!

Premier programme Lua

Programmation en mode interactif

Lua fournit un mode appelé mode interactif. Dans ce mode, vous pouvez taper les instructions les unes après les autres et obtenir des résultats instantanés. Cela peut être appelé dans le shell en utilisant la commande lua -i ou simplement la commande lua. Une fois que vous avez saisi ceci, appuyez sur Entrée et le mode interactif démarrera comme indiqué ci-dessous.

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

Vous pouvez imprimer quelque chose en utilisant l'instruction suivante -

print("test")

Une fois que vous appuyez sur Entrée, vous obtiendrez la sortie suivante -

test

Programmation du mode par défaut

L'appel de l'interpréteur avec un paramètre de nom de fichier Lua démarre l'exécution du fichier et continue jusqu'à ce que le script soit terminé. Lorsque le script est terminé, l'interpréteur n'est plus actif.

Écrivons un programme Lua simple. Tous les fichiers Lua auront l'extension .lua. Mettez donc le code source suivant dans un fichier test.lua.

print("test")

En supposant que l'environnement lua est correctement configuré, exécutons le programme en utilisant le code suivant -

$ lua test.lua

Nous obtiendrons la sortie suivante -

test

Essayons une autre façon d'exécuter un programme Lua. Voici le fichier test.lua modifié -

#!/usr/local/bin/lua

print("test")

Ici, nous avons supposé que l'interpréteur Lua était disponible dans votre répertoire / usr / local / bin. La première ligne est ignorée par l'interpréteur, si elle commence par le signe #. Maintenant, essayez d'exécuter ce programme comme suit -

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

Nous obtiendrons la sortie suivante.

test

Voyons maintenant la structure de base du programme Lua, afin qu'il vous soit facile de comprendre les éléments de base du langage de programmation Lua.

Jetons à Lua

Un programme Lua se compose de divers jetons et un jeton est soit un mot-clé, un identificateur, une constante, une chaîne littérale ou un symbole. Par exemple, l'instruction Lua suivante se compose de trois jetons -

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

Les jetons individuels sont -

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

commentaires

Les commentaires sont comme un texte d'aide dans votre programme Lua et ils sont ignorés par l'interpréteur. Ils commencent par - [[et se terminent par les caractères -]] comme indiqué ci-dessous -

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

Identifiants

Un identifiant Lua est un nom utilisé pour identifier une variable, une fonction ou tout autre élément défini par l'utilisateur. Un identificateur commence par une lettre «A à Z» ou «a à z» ou un trait de soulignement «_» suivi de zéro ou plusieurs lettres, traits de soulignement et chiffres (0 à 9).

Lua n'autorise pas les caractères de ponctuation tels que @, $ et% dans les identificateurs. Lua est uncase sensitivelangage de programmation. Ainsi, la main - d'œuvre et la main - d'œuvre sont deux identifiants différents dans Lua. Voici quelques exemples d'identifiants acceptables -

mohd         zara      abc     move_name    a_123
myname50     _temp     j       a23b9        retVal

Mots clés

La liste suivante montre quelques-uns des mots réservés en Lua. Ces mots réservés ne peuvent pas être utilisés comme constantes ou variables ou tout autre nom d'identifiant.

et Pause faire autre
sinon si fin faux pour
fonction si dans local
néant ne pas ou répéter
revenir puis vrai jusqu'à
tandis que

Espace blanc à Lua

Une ligne ne contenant que des espaces, éventuellement avec un commentaire, est connue comme une ligne vide, et un interpréteur Lua l'ignore totalement.

L'espace blanc est le terme utilisé dans Lua pour décrire les espaces, les tabulations, les caractères de nouvelle ligne et les commentaires. L'espace blanc sépare une partie d'une instruction d'une autre et permet à l'interpréteur d'identifier où se termine un élément d'une instruction, tel que int, et où commence l'élément suivant. Par conséquent, dans la déclaration suivante -

local age

Il doit y avoir au moins un caractère d'espacement (généralement un espace) entre local et age pour que l'interprète puisse les distinguer. D'autre part, dans la déclaration suivante -

fruit = apples + oranges   --get the total fruit

Aucun espace n'est nécessaire entre les fruits et =, ou entre = et les pommes, bien que vous soyez libre d'en inclure si vous le souhaitez à des fins de lisibilité.

Une variable n'est rien d'autre qu'un nom donné à une zone de stockage que nos programmes peuvent manipuler. Il peut contenir différents types de valeurs, notamment des fonctions et des tables.

Le nom d'une variable peut être composé de lettres, de chiffres et du caractère de soulignement. Il doit commencer par une lettre ou un trait de soulignement. Les lettres majuscules et minuscules sont distinctes car Lua est sensible à la casse. Il existe huit types de valeurs de base dans Lua -

Dans Lua, bien que nous n'ayons pas de types de données variables, nous avons trois types basés sur la portée de la variable.

  • Global variables - Toutes les variables sont considérées comme globales à moins qu'elles ne soient explicitement déclarées comme locales.

  • Local variables - Lorsque le type est spécifié comme local pour une variable, sa portée est limitée par les fonctions à l'intérieur de leur portée.

  • Table fields - C'est un type spécial de variable qui peut contenir tout sauf nil, y compris les fonctions.

Définition de variable dans Lua

Une définition de variable signifie dire à l'interpréteur où et combien créer le stockage pour la variable. Une définition de variable a un type facultatif et contient une liste d'une ou plusieurs variables de ce type comme suit -

type variable_list;

Ici, type est éventuellement local ou de type spécifié, ce qui le rend global, et variable_listpeut consister en un ou plusieurs noms d'identifiants séparés par des virgules. Certaines déclarations valides sont affichées ici -

local    i, j
local    i
local    a,c

La ligne local i, jà la fois déclare et définit les variables i et j; qui demande à l'interpréteur de créer des variables nommées i, j et limite la portée à être locale.

Les variables peuvent être initialisées (affectées d'une valeur initiale) dans leur déclaration. L'initialiseur se compose d'un signe égal suivi d'une expression constante comme suit -

type variable_list = value_list;

Quelques exemples sont -

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 --]]

Pour une définition sans initialiseur: les variables avec une durée de stockage statique sont implicitement initialisées avec nil.

Déclaration de variable en Lua

Comme vous pouvez le voir dans les exemples ci-dessus, les affectations de variables multiples suivent un format variable_list et value_list. Dans l'exemple ci-dessuslocal d, f = 5,10 nous avons d et f dans variable_list et 5 et 10 dans la liste de valeurs.

L'affectation de valeur dans Lua a lieu comme la première variable dans la variable_list avec la première valeur dans la value_list et ainsi de suite. Par conséquent, la valeur de d est 5 et la valeur de f est 10.

Exemple

Essayez l'exemple suivant, où les variables ont été déclarées en haut, mais elles ont été définies et initialisées dans la fonction 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)

Lorsque le code ci-dessus est construit et exécuté, il produit le résultat suivant -

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

Lvalues ​​et Rvalues ​​dans Lua

Il existe deux types d'expressions dans Lua -

  • lvalue- Les expressions qui font référence à un emplacement mémoire sont appelées expression "lvalue". Une lvalue peut apparaître comme le côté gauche ou droit d'une affectation.

  • rvalue- Le terme rvalue fait référence à une valeur de données qui est stockée à une certaine adresse en mémoire. Une rvalue est une expression qui ne peut pas avoir de valeur assignée, ce qui signifie qu'une rvalue peut apparaître sur le côté droit, mais pas sur le côté gauche d'une affectation.

Les variables sont des valeurs l et peuvent donc apparaître sur le côté gauche d'une affectation. Les littéraux numériques sont des valeurs r et ne peuvent donc pas être affectés et ne peuvent pas apparaître sur le côté gauche. Voici une déclaration valide -

g = 20

Mais suivre n'est pas une instruction valide et générerait une erreur de construction -

10 = 20

En langage de programmation Lua, en dehors des types d'affectation ci-dessus, il est possible d'avoir plusieurs lvalues ​​et rvalues ​​dans la même instruction unique. Il est montré ci-dessous.

g,l = 20,30

Dans l'énoncé ci-dessus, 20 est attribué à g et 30 est attribué à l.

Lua est un langage typé dynamiquement, donc les variables n'ont pas de types, seules les valeurs ont des types. Les valeurs peuvent être stockées dans des variables, transmises en tant que paramètres et renvoyées en tant que résultats.

Dans Lua, bien que nous n'ayons pas de types de données variables, mais nous avons des types pour les valeurs. La liste des types de données pour les valeurs est donnée ci-dessous.

Sr.Non Type de valeur et description
1

nil

Utilisé pour différencier la valeur d'avoir des données ou pas de données (nulles).

2

boolean

Inclut vrai et faux comme valeurs. Généralement utilisé pour la vérification de l'état.

3

number

Représente les nombres réels (virgule flottante double précision).

4

string

Représente un tableau de caractères.

5

function

Représente une méthode écrite en C ou Lua.

6

userdata

Représente des données C arbitraires.

sept

thread

Représente des threads d'exécution indépendants et est utilisé pour implémenter des coroutines.

8

table

Représente des tableaux ordinaires, des tables de symboles, des ensembles, des enregistrements, des graphiques, des arbres, etc., et implémente des tableaux associatifs. Il peut contenir n'importe quelle valeur (sauf nil).

Type Fonction

Dans Lua, il existe une fonction appelée 'type' qui nous permet de connaître le type de la variable. Quelques exemples sont donnés dans le code suivant.

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

Lorsque vous construisez et exécutez le programme ci-dessus, il produit le résultat suivant sous Linux -

string
number
boolean
function
nil
string

Par défaut, toutes les variables pointeront sur nil jusqu'à ce qu'elles reçoivent une valeur ou soient initialisées. Dans Lua, les chaînes nulles et vides sont considérées comme vraies en cas de vérification de condition. Par conséquent, vous devez être prudent lorsque vous utilisez des opérations booléennes. Nous en saurons plus sur l'utilisation de ces types dans les prochains chapitres.

Un opérateur est un symbole qui indique à l'interprète d'effectuer des manipulations mathématiques ou logiques spécifiques. Le langage Lua est riche en opérateurs intégrés et fournit les types d'opérateurs suivants -

  • Opérateurs arithmétiques
  • Opérateurs relationnels
  • Opérateurs logiques
  • Opérateurs divers

Ce tutoriel expliquera les opérateurs arithmétiques, relationnels, logiques et autres un par un.

Opérateurs arithmétiques

Le tableau suivant montre tous les opérateurs arithmétiques pris en charge par le langage Lua. Supposons une variableA détient 10 et variable B détient 20 alors -

Afficher des exemples

Opérateur La description Exemple
+ Ajoute deux opérandes A + B donnera 30
- Soustrait le deuxième opérande du premier A - B donnera -10
* Multiplier les deux opérandes A * B donnera 200
/ Diviser le numérateur par le dénumérateur B / A donnera 2
% Opérateur de module et reste après une division entière B% A donnera 0
^ L'opérateur exposant prend les exposants A ^ 2 donnera 100
- Unaire - l'opérateur agit comme une négation -A donnera -10

Opérateurs relationnels

Le tableau suivant montre tous les opérateurs relationnels pris en charge par le langage Lua. Supposons une variableA détient 10 et variable B détient 20 alors -

Afficher des exemples

Opérateur La description Exemple
== Vérifie si la valeur de deux opérandes est égale ou non, si oui, la condition devient vraie. (A == B) n'est pas vrai.
~ = Vérifie si la valeur de deux opérandes est égale ou non, si les valeurs ne sont pas égales, la condition devient vraie. (A ~ = B) est vrai.
> Vérifie si la valeur de l'opérande gauche est supérieure à la valeur de l'opérande droit, si oui, la condition devient vraie. (A> B) n'est pas vrai.
< Vérifie si la valeur de l'opérande gauche est inférieure à la valeur de l'opérande droit, si oui, la condition devient vraie. (A <B) est vrai.
> = Vérifie si la valeur de l'opérande gauche est supérieure ou égale à la valeur de l'opérande droit, si oui, la condition devient vraie. (A> = B) n'est pas vrai.
<= Vérifie si la valeur de l'opérande gauche est inférieure ou égale à la valeur de l'opérande droit, si oui, la condition devient vraie. (A <= B) est vrai.

Opérateurs logiques

Le tableau suivant montre tous les opérateurs logiques pris en charge par le langage Lua. Supposons une variableA est vrai et variable B est faux alors -

Afficher des exemples

Opérateur La description Exemple
et Opérateur logique ET appelé. Si les deux opérandes sont différents de zéro, la condition devient vraie. (A et B) est faux.
ou Opérateur OU logique appelé. Si l'un des deux opérandes est différent de zéro, la condition devient vraie. (A ou B) est vrai.
ne pas Opérateur PAS logique appelé. Utilisez pour inverser l'état logique de son opérande. Si une condition est vraie, l'opérateur NOT logique rendra faux. ! (A et B) est vrai.

Opérateurs divers

Les divers opérateurs pris en charge par Lua Language incluent concatenation et length.

Afficher des exemples

Opérateur La description Exemple
.. Concatène deux chaînes. a..b où a est "Hello" et b est "World", retournera "Hello World".
# Un opérateur unaire qui renvoie la longueur d'une chaîne ou d'une table. # "Hello" renverra 5

Priorité des opérateurs dans Lua

La priorité des opérateurs détermine le regroupement des termes dans une expression. Cela affecte la manière dont une expression est évaluée. Certains opérateurs ont une priorité plus élevée que d'autres; par exemple, l'opérateur de multiplication a une priorité plus élevée que l'opérateur d'addition -

Par exemple, x = 7 + 3 * 2; Ici, x est attribué à 13 et non à 20 car l'opérateur * a une priorité plus élevée que +, il est donc d'abord multiplié par 3 * 2, puis ajouté en 7.

Ici, les opérateurs avec la priorité la plus élevée apparaissent en haut du tableau, ceux avec la priorité la plus basse apparaissent en bas. Dans une expression, les opérateurs de priorité supérieure seront évalués en premier.

Afficher des exemples

Catégorie Opérateur Associativité
Unaire ne pas # - De droite à gauche
Enchaînement .. De droite à gauche
Multiplicatif * /% De gauche à droite
Additif + - De gauche à droite
Relationnel <> <=> = == ~ =  De gauche à droite
Égalité == ~ = De gauche à droite
ET logique et De gauche à droite
OU logique ou De gauche à droite

Il peut arriver que vous deviez exécuter un bloc de code plusieurs fois. En général, les instructions sont exécutées de façon séquentielle: la première instruction d'une fonction est exécutée en premier, suivie de la seconde, et ainsi de suite.

Les langages de programmation fournissent diverses structures de contrôle qui permettent des chemins d'exécution plus compliqués.

Une instruction de boucle nous permet d'exécuter une instruction ou un groupe d'instructions plusieurs fois. Voici la forme générale d'une instruction de boucle dans la plupart des langages de programmation -

Lua fournit les types de boucles suivants pour gérer les exigences de bouclage.

Sr.No. Type de boucle et description
1 boucle while

Répète une instruction ou un groupe d'instructions tant qu'une condition donnée est vraie. Il teste la condition avant d'exécuter le corps de la boucle.

2 pour boucle

Exécute une séquence d'instructions plusieurs fois et abrége le code qui gère la variable de boucle.

3 répéter ... jusqu'à boucle

Répète l'opération du groupe d'instructions jusqu'à ce que la condition jusqu'à ce que soit remplie.

4 boucles imbriquées

Vous pouvez utiliser une ou plusieurs boucles à l'intérieur d'une autre boucle while, for ou do.. while.

Déclaration de contrôle de boucle

L'instruction de contrôle de boucle change l'exécution de sa séquence normale. Lorsque l'exécution quitte une étendue, tous les objets automatiques qui ont été créés dans cette étendue sont détruits.

Lua prend en charge les instructions de contrôle suivantes.

Sr.No. Déclaration de contrôle et description
1 déclaration break

Met fin au loop et transfère l'exécution à l'instruction immédiatement après la boucle ou le commutateur.

La boucle infinie

Une boucle devient une boucle infinie si une condition ne devient jamais fausse. lewhileloop est souvent utilisé à cette fin. Puisque nous donnons directement vrai pour la condition, elle continue de s'exécuter pour toujours. Nous pouvons utiliser l'instruction break pour rompre cette boucle.

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

Les structures de prise de décision exigent que le programmeur spécifie une ou plusieurs conditions à évaluer ou à tester par le programme, ainsi qu'une ou plusieurs instructions à exécuter, si la condition est jugée vraie, et éventuellement d'autres instructions à exécuter si le condition est considérée comme fausse.

Voici la forme générale d'une structure de prise de décision typique trouvée dans la plupart des langages de programmation -

Le langage de programmation Lua suppose n'importe quelle combinaison de booléen true et non-nil valeurs comme true, et si c'est booléen false ou nil, alors il est supposé comme falsevaleur. Il est à noter qu'à Lua,zero will be considered as true.

Le langage de programmation Lua fournit les types suivants d'énoncés de prise de décision.

Sr.No. Déclaration et description
1 si déclaration

Une instruction if consiste en une expression booléenne suivie d'une ou plusieurs instructions.

2 instruction if ... else

Une instruction if peut être suivie d'une instruction else facultative , qui s'exécute lorsque l'expression booléenne est fausse.

3 instructions if imbriquées

Vous pouvez utiliser une instruction if ou else if dans une autre instruction if ou else if .

Une fonction est un groupe d'instructions qui exécutent ensemble une tâche. Vous pouvez diviser votre code en fonctions distinctes. La façon dont vous divisez votre code entre différentes fonctions dépend de vous, mais logiquement, la division généralement unique est que chaque fonction effectue une tâche spécifique.

Le langage Lua fournit de nombreuses méthodes intégrées que votre programme peut appeler. Par exemple, méthodeprint() pour imprimer l'argument passé en entrée dans la console.

Une fonction est connue sous différents noms comme une méthode ou une sous-routine ou une procédure etc.

Définition d'une fonction

La forme générale d'une définition de méthode dans le langage de programmation Lua est la suivante -

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

Une définition de méthode dans le langage de programmation Lua se compose d'un en- tête de méthode et d'un corps de méthode . Voici toutes les parties d'une méthode -

  • Optional Function Scope- Vous pouvez utiliser le mot clé local pour limiter la portée de la fonction ou ignorer la section scope, ce qui en fera une fonction globale.

  • Function Name- Ceci est le nom réel de la fonction. Le nom de la fonction et la liste des paramètres constituent ensemble la signature de la fonction.

  • Arguments- Un argument est comme un espace réservé. Lorsqu'une fonction est appelée, vous transmettez une valeur à l'argument. Cette valeur est appelée paramètre ou argument réel. La liste des paramètres fait référence au type, à l'ordre et au nombre d'arguments d'une méthode. Les arguments sont facultatifs; autrement dit, une méthode peut ne contenir aucun argument.

  • Function Body - Le corps de la méthode contient une collection d'instructions qui définissent ce que fait la méthode.

  • Return - Dans Lua, il est possible de renvoyer plusieurs valeurs en suivant le mot-clé return avec les valeurs de retour séparées par des virgules.

Exemple

Voici le code source d'une fonction appelée max(). Cette fonction prend deux paramètres num1 et num2 et renvoie le maximum entre les deux -

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

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

   return result; 
end

Arguments de fonction

Si une fonction doit utiliser des arguments, elle doit déclarer les variables qui acceptent les valeurs des arguments. Ces variables sont appeléesformal parameters de la fonction.

Les paramètres formels se comportent comme les autres variables locales à l'intérieur de la fonction et sont créés à l'entrée dans la fonction et détruits à la sortie.

Appeler une fonction

Lors de la création d'une fonction Lua, vous donnez une définition de ce que la fonction doit faire. Pour utiliser une méthode, vous devrez appeler cette fonction pour exécuter la tâche définie.

Lorsqu'un programme appelle une fonction, le contrôle du programme est transféré à la fonction appelée. Une fonction appelée exécute la tâche définie et lorsque son instruction return est exécutée ou lorsque la fin de sa fonction est atteinte, elle renvoie le contrôle du programme au programme principal.

Pour appeler une méthode, vous devez simplement transmettre les paramètres requis avec le nom de la méthode et si la méthode renvoie une valeur, vous pouvez stocker la valeur retournée. Par exemple -

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))

Lorsque nous exécutons le code ci-dessus, nous obtiendrons la sortie suivante.

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

Assigner et transmettre des fonctions

Dans Lua, nous pouvons attribuer la fonction à des variables et également les transmettre en tant que paramètres d'une autre fonction. Voici un exemple simple pour affecter et passer une fonction en tant que paramètre dans 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)

Lorsque nous exécutons le code ci-dessus, nous obtiendrons la sortie suivante.

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

Fonction avec argument variable

Il est possible de créer des fonctions avec des arguments variables dans Lua en utilisant '...' comme paramètre. Nous pouvons comprendre cela en voyant un exemple dans lequel la fonction retournera la moyenne et elle peut prendre des arguments variables.

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))

Lorsque nous exécutons le code ci-dessus, nous obtiendrons la sortie suivante.

The average is	5.5

La chaîne est une séquence de caractères ainsi que des caractères de contrôle comme le saut de formulaire. La chaîne peut être initialisée avec trois formes qui incluent -

  • Caractères entre guillemets simples
  • Caractères entre guillemets
  • Caractères entre [[et]]

Un exemple des trois formulaires ci-dessus est présenté ci-dessous.

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

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

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

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

Les caractères de séquence d'échappement sont utilisés dans la chaîne pour modifier l'interprétation normale des caractères. Par exemple, pour imprimer des doubles virgules inversées (""), nous avons utilisé \ "dans l'exemple ci-dessus. La séquence d'échappement et son utilisation sont répertoriées ci-dessous dans le tableau.

Séquence d'échappement Utilisation
\une Cloche
\ b Retour arrière
\F Formfeed
\ n Nouvelle ligne
\ r Retour chariot
\ t Languette
\ v Onglet vertical
\\ Barre oblique inverse
\ " Double citation
\ ' Guillemets simples
\ [ Support carré gauche
\] Support carré droit

Manipulation de chaînes

Lua prend en charge la chaîne pour manipuler les chaînes -

Sr.No. Méthode et objectif
1

string.upper(argument)

Renvoie une représentation en majuscule de l'argument.

2

string.lower(argument)

Renvoie une représentation en minuscules de l'argument.

3

string.gsub(mainString,findString,replaceString)

Renvoie une chaîne en remplaçant les occurrences de findString par replaceString.

4

string.find(mainString,findString,

optionalStartIndex,optionalEndIndex)

Renvoie l'index de début et l'index de fin de findString dans la chaîne principale et nil s'il n'est pas trouvé.

5

string.reverse(arg)

Renvoie une chaîne en inversant les caractères de la chaîne transmise.

6

string.format(...)

Renvoie une chaîne formatée.

sept

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

Renvoie des représentations numériques et caractères internes de l'argument d'entrée.

8

string.len(arg)

Renvoie une longueur de la chaîne transmise.

9

string.rep(string, n))

Renvoie une chaîne en répétant la même chaîne n fois.

dix

..

Ainsi, l'opérateur concatène deux chaînes.

Maintenant, plongons dans quelques exemples pour voir exactement comment ces fonctions de manipulation de chaînes se comportent.

Manipulation de cas

Un exemple de code pour manipuler les chaînes en majuscules et minuscules est donné ci-dessous.

string1 = "Lua";

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

LUA
lua

Remplacement d'une sous-chaîne

Un exemple de code pour remplacer les occurrences d'une chaîne par une autre est donné ci-dessous.

string = "Lua Tutorial"

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

The new string is Lua Language

Trouver et inverser

Un exemple de code pour rechercher l'index de la sous-chaîne et de la chaîne d'inversion est donné ci-dessous.

string = "Lua Tutorial"

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

5	12
The new string is	lairotuT auL

Formatage des chaînes

Plusieurs fois dans notre programmation, nous pouvons avoir besoin d'imprimer des chaînes de manière formatée. Vous pouvez utiliser la fonction string.format pour formater la sortie comme indiqué ci-dessous.

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))

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

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

Représentations de caractères et d'octets

Un exemple de code pour la représentation de caractères et d'octets, qui est utilisé pour convertir la chaîne de chaîne en représentation interne et vice versa.

-- 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))

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

76
97
97
117
117
a

Autres fonctions communes

Les manipulations de chaîne courantes incluent la concaténation de chaînes, la recherche de la longueur de la chaîne et parfois la répétition de la même chaîne plusieurs fois. L'exemple de ces opérations est donné ci-dessous.

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)

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

Concatenated string	LuaTutorial
Length of string1 is 	3
LuaLuaLua

Les tableaux sont un agencement ordonné d'objets, qui peut être un tableau unidimensionnel contenant une collection de lignes ou un tableau multidimensionnel contenant plusieurs lignes et colonnes.

Dans Lua, les tableaux sont implémentés à l'aide de tables d'indexation avec des entiers. La taille d'un tableau n'est pas fixe et peut augmenter en fonction de nos besoins, sous réserve de contraintes de mémoire.

Réseau unidimensionnel

Un tableau unidimensionnel peut être représenté à l'aide d'une structure de table simple et peut être initialisé et lu à l'aide d'un simple forboucle. Un exemple est présenté ci-dessous.

array = {"Lua", "Tutorial"}

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

Lorsque nous exécutons le code ci-dessus, nous obtenons la sortie suivante.

nil
Lua
Tutorial

Comme vous pouvez le voir dans le code ci-dessus, lorsque nous essayons d'accéder à un élément dans un index qui n'est pas là dans le tableau, il renvoie nil. Dans Lua, l'indexation commence généralement à l'index 1. Mais il est également possible de créer des objets à l'index 0 et au-dessous de 0. Un tableau utilisant des indices négatifs est montré ci-dessous où nous initialisons le tableau à l'aide d'une boucle for .

array = {}

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

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

Lorsque nous exécutons le code ci-dessus, nous obtiendrons la sortie suivante.

-4
-2
0
2
4

Réseau multidimensionnel

Les tableaux multidimensionnels peuvent être implémentés de deux manières.

  • Tableau de tableaux
  • Tableau unidimensionnel en manipulant des indices

Un exemple de tableau multidimensionnel de 3. 3 est illustré ci-dessous en utilisant un tableau de tableaux.

-- 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

Lorsque nous exécutons le code ci-dessus, nous obtiendrons la sortie suivante.

1
2
3
2
4
6
3
6
9

Un exemple de tableau multidimensionnel est illustré ci-dessous à l'aide d'indices de manipulation.

-- 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

Lorsque nous exécutons le code ci-dessus, nous obtiendrons la sortie suivante.

1
2
3
2
4
6
3
6
9

Comme vous pouvez le voir dans l'exemple ci-dessus, les données sont stockées sur la base d'indices. Il est possible de placer les éléments de manière clairsemée et c'est ainsi que fonctionne l'implémentation Lua d'une matrice. Comme il ne stocke pas de valeurs nulles dans Lua, il est possible d'économiser beaucoup de mémoire sans aucune technique spéciale dans Lua par rapport aux techniques spéciales utilisées dans d'autres langages de programmation.

Iterator est une construction qui vous permet de parcourir les éléments de la soi-disant collection ou conteneur. Dans Lua, ces collections font souvent référence à des tables, qui sont utilisées pour créer diverses structures de données comme un tableau.

Générique pour Iterator

Un générique pour itérateur fournit des paires de valeurs clés de chaque élément de la collection. Un exemple simple est donné ci-dessous.

array = {"Lua", "Tutorial"}

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

Lorsque nous exécutons le code ci-dessus, nous obtiendrons la sortie suivante -

1  Lua
2  Tutorial

L'exemple ci-dessus utilise la fonction d'itérateur ipairs par défaut fournie par Lua.

Dans Lua, nous utilisons des fonctions pour représenter les itérateurs. Sur la base de la maintenance de l'état dans ces fonctions d'itération, nous avons deux types principaux -

  • Itérateurs apatrides
  • Itérateurs avec état

Itérateurs apatrides

Par le nom lui-même, nous pouvons comprendre que ce type de fonction d'itérateur ne conserve aucun état.

Voyons maintenant un exemple de création de notre propre itérateur en utilisant une fonction simple qui imprime les carrés de n Nombres.

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

1	1
2	4
3	9

Le code ci-dessus peut être légèrement modifié pour imiter le fonctionnement de la fonction ipairs des itérateurs. Il est montré ci-dessous.

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

1	1
2	4
3	9

Itérateurs avec état

L'exemple précédent d'itération utilisant la fonction ne conserve pas l'état. Chaque fois que la fonction est appelée, elle renvoie l'élément suivant de la collection en fonction d'une deuxième variable envoyée à la fonction. Pour conserver l'état de l'élément actuel, des fermetures sont utilisées. La fermeture conserve les valeurs des variables à travers les appels de fonctions. Pour créer une nouvelle fermeture, nous créons deux fonctions dont la fermeture elle-même et une usine, la fonction qui crée la fermeture.

Voyons maintenant un exemple de création de notre propre itérateur dans lequel nous utiliserons des fermetures.

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

Lua
Tutorial

Dans l'exemple ci-dessus, nous pouvons voir que elementIterator a une autre méthode à l'intérieur qui utilise les variables externes locales index et count pour renvoyer chacun des éléments de la collection en incrémentant l'index chaque fois que la fonction est appelée.

Nous pouvons créer nos propres itérateurs de fonction en utilisant la fermeture comme indiqué ci-dessus et il peut renvoyer plusieurs éléments pour chaque fois que nous itérons dans la collection.

introduction

Les tableaux sont la seule structure de données disponible dans Lua qui nous aide à créer différents types tels que des tableaux et des dictionnaires. Lua utilise des tableaux associatifs et qui peuvent être indexés non seulement avec des nombres mais aussi avec des chaînes sauf nil. Les tables n'ont pas de taille fixe et peuvent évoluer en fonction de nos besoins.

Lua utilise des tables dans toutes les représentations, y compris la représentation des packages. Lorsque nous accédons à une méthode string.format, cela signifie que nous accédons à la fonction format disponible dans le package string.

Représentation et utilisation

Les tableaux sont appelés objets et ne sont ni des valeurs ni des variables. Lua utilise une expression de constructeur {} pour créer une table vide. Il faut savoir qu'il n'y a pas de relation fixe entre une variable qui contient la référence de la table et la table elle-même.

--sample table initialization
mytable = {}

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

--removing reference
mytable = nil

-- lua garbage collection will take care of releasing memory

Quand nous avons une table a avec un ensemble d'éléments et si nous l'attribuons à b, tous les deux a et bse réfèrent à la même mémoire. Aucune mémoire séparée n'est allouée séparément pour b. Lorsque a est défini sur nil, la table sera toujours accessible à b. Lorsqu'il n'y a pas de référence à une table, le garbage collection dans Lua s'occupe du processus de nettoyage pour que ces mémoires non référencées soient réutilisées à nouveau.

Un exemple est présenté ci-dessous pour expliquer les caractéristiques des tableaux mentionnées ci-dessus.

-- 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)

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante -

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

Manipulation de table

Il existe des fonctions intégrées pour la manipulation de table et elles sont répertoriées dans le tableau suivant.

Sr.No. Méthode et objectif
1

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

Concatène les chaînes dans les tables en fonction des paramètres donnés. Voir l'exemple pour plus de détails.

2

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

Insère une valeur dans la table à la position spécifiée.

3

table.maxn (table)

Renvoie le plus grand index numérique.

4

table.remove (table [, pos])

Supprime la valeur de la table.

5

table.sort (table [, comp])

Trie la table en fonction de l'argument de comparateur facultatif.

Voyons quelques exemples des fonctions ci-dessus.

Concaténation de table

Nous pouvons utiliser la fonction concat pour concaténer deux tables comme indiqué ci-dessous -

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))

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante -

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

Insérer et supprimer

L'insertion et la suppression d'éléments dans les tableaux sont les plus courantes dans la manipulation de tableaux. Cela est expliqué ci-dessous.

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])

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante -

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

Tri des tableaux

Nous avons souvent besoin de trier une table dans un ordre particulier. Les fonctions de tri trient les éléments d'un tableau par ordre alphabétique. Un exemple de ceci est présenté ci-dessous.

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante -

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

Qu'est-ce qu'un module?

Le module est comme une bibliothèque qui peut être chargée à l'aide de require et a un seul nom global contenant une table. Ce module peut comprendre un certain nombre de fonctions et de variables. Toutes ces fonctions et variables sont encapsulées dans la table, qui agit comme un espace de noms. De plus, un module bien comporté dispose des dispositions nécessaires pour renvoyer ce tableau sur demande.

Spécialité des modules Lua

L'utilisation de tables dans les modules nous aide de nombreuses manières et nous permet de manipuler les modules de la même manière que nous manipulons n'importe quelle autre table Lua. En raison de la possibilité de manipuler des modules, il fournit des fonctionnalités supplémentaires pour lesquelles d'autres langages ont besoin de mécanismes spéciaux. En raison de ce mécanisme gratuit de modules dans Lua, un utilisateur peut appeler les fonctions dans Lua de plusieurs manières. Quelques-uns d'entre eux sont présentés ci-dessous.

-- 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")

Dans l'exemple de code ci-dessus, vous pouvez voir à quel point la programmation flexible dans Lua est, sans aucun code supplémentaire spécial.

La fonction requise

Lua a fourni une fonction de haut niveau appelée require pour charger tous les modules nécessaires. Il est maintenu aussi simple que possible pour éviter d'avoir trop d'informations sur le module pour le charger. La fonction require suppose simplement les modules comme un morceau de code qui définit certaines valeurs, qui sont en fait des fonctions ou des tables contenant des fonctions.

Exemple

Prenons un exemple simple, où une fonction a les fonctions mathématiques. Appelons ce module comme mymath et le nom de fichier étant mymath.lua. Le contenu du fichier est le suivant -

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

Maintenant, pour accéder à ce module Lua dans un autre fichier, par exemple moduletutorial.lua, vous devez utiliser le segment de code suivant.

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

Pour exécuter ce code, nous devons placer les deux fichiers Lua dans le même répertoire ou vous pouvez également placer le fichier du module dans le chemin du package et il nécessite une configuration supplémentaire. Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

30
10
200
1.5

Choses dont il faut se rappeler

  • Placez les modules et le fichier que vous exécutez dans le même répertoire.

  • Le nom du module et son nom de fichier doivent être identiques.

  • Il est recommandé de renvoyer des modules pour la fonction require et, par conséquent, le module doit être de préférence implémenté comme indiqué ci-dessus, même si vous pouvez trouver d'autres types d'implémentations ailleurs.

Ancienne méthode de mise en œuvre des modules

Permettez-moi maintenant de réécrire le même exemple à l'ancienne, qui utilise le type d'implémentation package.seeall. Cela a été utilisé dans les versions 5.1 et 5.0 de Lua. Le module mymath est illustré ci-dessous.

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

L'utilisation des modules dans moduletutorial.lua est illustrée ci-dessous.

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

Lorsque nous exécutons ce qui précède, nous obtiendrons le même résultat. Mais il est conseillé d'utiliser l'ancienne version du code et elle est supposée moins sécurisée. De nombreux SDK qui utilisent Lua pour la programmation comme le SDK Corona en ont déconseillé l'utilisation.

Une métatable est une table qui aide à modifier le comportement d'une table à laquelle elle est attachée à l'aide d'un jeu de clés et des méta-méthodes associées. Ces méta-méthodes sont de puissantes fonctionnalités Lua qui permettent des fonctionnalités telles que -

  • Modification / ajout de fonctionnalités aux opérateurs sur les tables.

  • Recherche de métatables lorsque la clé n'est pas disponible dans la table à l'aide de __index dans métatable.

Il existe deux méthodes importantes utilisées pour gérer les métatables, notamment:

  • setmetatable(table,metatable) - Cette méthode est utilisée pour définir métatable pour une table.

  • getmetatable(table) - Cette méthode est utilisée pour obtenir la métatable d'une table.

Voyons d'abord comment définir une table comme métatable d'une autre. Il est montré ci-dessous.

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

Le code ci-dessus peut être représenté sur une seule ligne comme indiqué ci-dessous.

mytable = setmetatable({},{})

_indice

Un exemple simple de métatable pour rechercher la méta-table lorsqu'elle n'est pas disponible dans le tableau est illustré ci-dessous.

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)

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

value1 metatablevalue

Expliquons par étapes ce qui s'est passé dans l'exemple ci-dessus.

  • Le tableau mytable ici est {key1 = "value1"}.

  • Metatable est défini pour mytable qui contient une fonction pour __index, que nous appelons une métaméthode.

  • La métaméthode fait un simple travail de recherche d'un index "key2", s'il est trouvé, il retourne "metatablevalue", sinon retourne la valeur de mytable pour l'index correspondant.

Nous pouvons avoir une version simplifiée du programme ci-dessus comme indiqué ci-dessous.

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

__newindex

Lorsque nous ajoutons __newindex à metatable, si les clés ne sont pas disponibles dans la table, le comportement des nouvelles clés sera défini par des méta-méthodes. Un exemple simple où l'index de metatable est défini lorsque l'index n'est pas disponible dans la table principale est donné ci-dessous.

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)

Lorsque vous exécutez le programme ci-dessus, vous obtenez la sortie suivante.

value1
nil	new value 2
new  value 1	nil

Vous pouvez voir dans le programme ci-dessus, si une clé existe dans la table principale, elle la met simplement à jour. Lorsqu'une clé n'est pas disponible dans le maintable, il ajoute cette clé au métatable.

Un autre exemple qui met à jour la même table à l'aide de la fonction rawset est illustré ci-dessous.

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)

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

new value	"4"

rawset définit la valeur sans utiliser __newindex de métatable. De même, il y a rawget qui obtient de la valeur sans utiliser __index.

Ajout d'un comportement d'opérateur aux tables

Un exemple simple pour combiner deux tables à l'aide de l'opérateur + est présenté ci-dessous -

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

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

La clé __add est incluse dans la métatable pour ajouter le comportement de operator +. Le tableau des touches et de l'opérateur correspondant est présenté ci-dessous.

Sr.No. Mode et description
1

__add

Modifie le comportement de l'opérateur «+».

2

__sub

Modifie le comportement de l'opérateur «-».

3

__mul

Modifie le comportement de l'opérateur «*».

4

__div

Modifie le comportement de l'opérateur «/».

5

__mod

Modifie le comportement de l'opérateur '%'.

6

__unm

Modifie le comportement de l'opérateur «-».

sept

__concat

Modifie le comportement de l'opérateur «..».

8

__eq

Modifie le comportement de l'opérateur '=='.

9

__lt

Modifie le comportement de l'opérateur «<».

dix

__le

Modifie le comportement de l'opérateur '<='.

__appel

L'ajout du comportement de l'appel de méthode se fait à l'aide de l'instruction __call. Un exemple simple qui renvoie la somme des valeurs de la table principale avec la table passée.

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))

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

70

__tostring

Pour modifier le comportement de l'instruction d'impression, nous pouvons utiliser la métaméthode __tostring. Un exemple simple est présenté ci-dessous.

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)

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

The sum of values in the table is 60

Si vous connaissez parfaitement les capacités de la méta-table, vous pouvez vraiment effectuer de nombreuses opérations qui seraient très complexes sans l'utiliser. Alors, essayez de travailler davantage sur l'utilisation des métatables avec différentes options disponibles dans les méta-tables comme expliqué dans les exemples et créez également vos propres échantillons.

introduction

Les coroutines sont de nature collaborative, ce qui permet à deux méthodes ou plus de s'exécuter de manière contrôlée. Avec les coroutines, à tout moment, une seule coroutine s'exécute et cette coroutine en cours d'exécution ne suspend son exécution que lorsqu'elle demande explicitement à être suspendue.

La définition ci-dessus peut paraître vague. Supposons que nous ayons deux méthodes, une méthode du programme principal et une coroutine. Lorsque nous appelons une coroutine en utilisant la fonction de reprise, son exécution commence et lorsque nous appelons la fonction yield, elle suspend l'exécution. Encore une fois, la même coroutine peut continuer à s'exécuter avec un autre appel de fonction de reprise à partir de l'endroit où elle a été suspendue. Ce processus peut se poursuivre jusqu'à la fin de l'exécution de la coroutine.

Fonctions disponibles dans les coroutines

Le tableau suivant répertorie toutes les fonctions disponibles pour les coroutines dans Lua et leur utilisation correspondante.

Sr.No. Méthode et objectif
1

coroutine.create (f)

Crée une nouvelle coroutine avec une fonction f et retourne un objet de type "thread".

2

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

Reprend la coroutine co et passe les paramètres le cas échéant. Il renvoie l'état de l'opération et d'autres valeurs de retour facultatives.

3

coroutine.running ()

Renvoie la coroutine en cours d'exécution ou nil si elle est appelée dans le thread principal.

4

coroutine.status (co)

Renvoie l'une des valeurs de fonctionnement, normal, suspendu ou mort en fonction de l'état de la coroutine.

5

coroutine.wrap (f)

Comme coroutine.create, la fonction coroutine.wrap crée également une coroutine, mais au lieu de renvoyer la coroutine elle-même, elle renvoie une fonction qui, lorsqu'elle est appelée, reprend la coroutine.

6

coroutine.yield (...)

Suspend la coroutine en cours d'exécution. Le paramètre passé à cette méthode agit comme des valeurs de retour supplémentaires pour la fonction de reprise.

Exemple

Regardons un exemple pour comprendre le concept de coroutines.

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))

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

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

Que fait l'exemple ci-dessus?

Comme mentionné précédemment, nous utilisons la fonction de reprise pour démarrer l'opération et la fonction de rendement pour arrêter l'opération. En outre, vous pouvez voir qu'il existe plusieurs valeurs de retour reçues par la fonction de reprise de coroutine.

  • Tout d'abord, nous créons une coroutine et l'affectons à un nom de variable co et la coroutine prend deux variables comme paramètres.

  • Lorsque nous appelons la première fonction de reprise, les valeurs 3 et 2 sont conservées dans les variables temporaires value1 et value2 jusqu'à la fin de la coroutine.

  • Pour vous faire comprendre, nous avons utilisé une tempvar3, qui vaut initialement 10 et elle est mise à jour à 13 et 16 par les appels ultérieurs des coroutines puisque value1 est conservée à 3 tout au long de l'exécution de la coroutine.

  • Le premier coroutine.yield renvoie deux valeurs 4 et 3 à la fonction de reprise, que nous obtenons en mettant à jour les paramètres d'entrée 3 et 2 dans l'instruction yield. Il reçoit également le statut vrai / faux de l'exécution de la coroutine.

  • Une autre chose à propos des coroutines est la façon dont les paramètres suivants de l'appel de reprise sont pris en charge, dans l'exemple ci-dessus; vous pouvez voir que la variable coroutine.yield reçoit les prochains paramètres d'appel, ce qui fournit un moyen puissant de faire une nouvelle opération avec la rétention des valeurs de paramètres existantes.

  • Enfin, une fois que toutes les instructions dans les coroutines sont exécutées, les appels suivants reviendront en faux et "ne peut pas reprendre la coroutine morte" comme réponse.

Un autre exemple de Coroutine

Regardons une simple coroutine qui renvoie un nombre de 1 à 5 à l'aide de la fonction yield et de la fonction de reprise. Il crée la coroutine si elle n'est pas disponible ou bien reprend la coroutine existante.

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

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

Il y a souvent une comparaison des coroutines avec les threads des langages de multiprogrammation, mais nous devons comprendre que les coroutines ont des caractéristiques similaires de thread mais elles ne s'exécutent qu'une à la fois et ne s'exécutent jamais simultanément.

Nous contrôlons la séquence d'exécution du programme pour répondre aux besoins en conservant temporairement certaines informations. L'utilisation de variables globales avec des coroutines offre encore plus de flexibilité aux coroutines.

La bibliothèque d'E / S est utilisée pour lire et manipuler des fichiers dans Lua. Il existe deux types d'opérations sur les fichiers dans Lua, à savoir les descripteurs de fichiers implicites et les descripteurs de fichiers explicites.

Pour les exemples suivants, nous utiliserons un exemple de fichier test.lua comme indiqué ci-dessous.

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

Une simple opération d'ouverture de fichier utilise l'instruction suivante.

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

Les différents modes de fichier sont répertoriés dans le tableau suivant.

Sr.No. Mode et description
1

"r"

Mode lecture seule et est le mode par défaut où un fichier existant est ouvert.

2

"w"

Mode d'écriture activé qui écrase le fichier existant ou crée un nouveau fichier.

3

"a"

Mode d'ajout qui ouvre un fichier existant ou crée un nouveau fichier à ajouter.

4

"r+"

Mode lecture et écriture pour un fichier existant.

5

"w+"

Toutes les données existantes sont supprimées si le fichier existe ou si un nouveau fichier est créé avec des autorisations de lecture / écriture.

6

"a+"

Mode d'ajout avec le mode de lecture activé qui ouvre un fichier existant ou crée un nouveau fichier.

Descripteurs de fichier implicites

Les descripteurs de fichiers implicites utilisent les modes d'entrée / sortie standard ou en utilisant un seul fichier d'entrée et un seul fichier de sortie. Un exemple d'utilisation de descripteurs de fichiers implicites est présenté ci-dessous.

-- 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)

Lorsque vous exécutez le programme, vous obtiendrez une sortie de la première ligne du fichier test.lua. Pour notre programme, nous avons obtenu la sortie suivante.

-- Sample test.lua

C'était la première ligne de l'instruction dans le fichier test.lua pour nous. La ligne "- Fin du fichier test.lua" serait également ajoutée à la dernière ligne du code test.lua.

Dans l'exemple ci-dessus, vous pouvez voir comment les descripteurs implicites fonctionnent avec le système de fichiers en utilisant les méthodes io. "X". L'exemple ci-dessus utilise io.read () sans le paramètre facultatif. Le paramètre facultatif peut être l'un des suivants.

Sr.No. Mode et description
1

"*n"

Lit la position actuelle du fichier et renvoie un nombre s'il existe à la position du fichier ou renvoie nul.

2

"*a"

Renvoie tout le contenu du fichier à partir de la position actuelle du fichier.

3

"*l"

Lit la ligne à partir de la position actuelle du fichier et déplace la position du fichier vers la ligne suivante.

4

number

Lit le nombre d'octets spécifié dans la fonction.

D'autres méthodes d'E / S courantes comprennent:

  • io.tmpfile() - Renvoie un fichier temporaire pour la lecture et l'écriture qui sera supprimé une fois le programme fermé.

  • io.type(file) - Retourne si fichier, fichier fermé ou nil basé sur le fichier d'entrée.

  • io.flush() - Efface le tampon de sortie par défaut.

  • io.lines(optional file name)- Fournit un itérateur de boucle for générique qui parcourt le fichier et ferme le fichier à la fin, au cas où le nom de fichier est fourni ou si le fichier par défaut est utilisé et non fermé à la fin de la boucle.

Descripteurs de fichier explicites

Nous utilisons souvent un descripteur de fichier explicite qui nous permet de manipuler plusieurs fichiers à la fois. Ces fonctions sont assez similaires aux descripteurs de fichiers implicites. Ici, nous utilisons file: nom_fonction au lieu de io.fonction_nom. L'exemple suivant de la version de fichier du même exemple de descripteurs de fichiers implicites est illustré ci-dessous.

-- 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()

Lorsque vous exécutez le programme, vous obtiendrez une sortie similaire à l'exemple de descripteurs implicites.

-- Sample test.lua

Tous les modes d'ouverture de fichier et de paramètres de lecture pour les descripteurs externes sont identiques à ceux des descripteurs de fichiers implicites.

D'autres méthodes de fichier courantes comprennent,

  • file:seek(optional whence, optional offset)- D'où le paramètre est "set", "cur" ou "end". Définit le nouveau pointeur de fichier avec la position de fichier mise à jour depuis le début du fichier. Les décalages sont basés sur zéro dans cette fonction. Le décalage est mesuré à partir du début du fichier si le premier argument est "set"; à partir de la position actuelle dans le fichier si c'est "cur"; ou à partir de la fin du fichier s'il est "end". Les valeurs d'argument par défaut sont "cur" et 0, donc la position actuelle du fichier peut être obtenue en appelant cette fonction sans arguments.

  • file:flush() - Efface le tampon de sortie par défaut.

  • io.lines(optional file name)- Fournit un itérateur de boucle for générique qui parcourt le fichier et ferme le fichier à la fin, au cas où le nom de fichier est fourni ou si le fichier par défaut est utilisé et non fermé à la fin de la boucle.

Un exemple d'utilisation de la méthode de recherche est présenté ci-dessous. Il décale le curseur des 25 positions avant la fin du fichier. La fonction de lecture imprime le reste du fichier à partir de la position de recherche.

-- 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()

Vous obtiendrez une sortie similaire à la suivante.

sample2 test.lua
--test

Vous pouvez jouer avec tous les différents modes et paramètres pour connaître la pleine capacité des opérations sur les fichiers Lua.

Nécessité d'une gestion des erreurs

La gestion des erreurs est assez critique car les opérations du monde réel nécessitent souvent l'utilisation d'opérations complexes, qui incluent des opérations sur les fichiers, des transactions de base de données et des appels de service Web.

Dans toute programmation, il y a toujours une exigence pour la gestion des erreurs. Les erreurs peuvent être de deux types, notamment:

  • Erreurs de syntaxe
  • Erreurs d'exécution

Erreurs de syntaxe

Des erreurs de syntaxe se produisent en raison d'une mauvaise utilisation de divers composants du programme tels que des opérateurs et des expressions. Un exemple simple d'erreur de syntaxe est présenté ci-dessous.

a == 2

Comme vous le savez, il y a une différence entre l'utilisation d'un simple «égal à» et d'un double «égal à». L'utilisation de l'un au lieu de l'autre peut entraîner une erreur. Un «égal à» fait référence à l'assignation tandis qu'un double «égal à» fait référence à la comparaison. De même, nous avons des expressions et des fonctions ayant leurs modes d'implémentation prédéfinis.

Un autre exemple d'erreur de syntaxe est présenté ci-dessous -

for a= 1,10
   print(a)
end

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante -

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

Les erreurs de syntaxe sont beaucoup plus faciles à gérer que les erreurs d'exécution car l'interpréteur Lua localise l'erreur plus clairement qu'en cas d'erreur d'exécution. À partir de l'erreur ci-dessus, nous pouvons facilement savoir que l'ajout d'une instruction do avant l'instruction print est nécessaire selon la structure Lua.

Erreurs d'exécution

En cas d'erreurs d'exécution, le programme s'exécute avec succès, mais cela peut entraîner des erreurs d'exécution dues à des erreurs de saisie ou à des fonctions mal gérées. Un exemple simple pour montrer l'erreur d'exécution est présenté ci-dessous.

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

add(10)

Lorsque nous construisons le programme, il se construit avec succès et s'exécute. Une fois qu'il s'exécute, affiche une erreur d'exécution.

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]: ?

Il s'agit d'une erreur d'exécution, qui s'est produite en raison du non-passage de deux variables. leb paramètre est attendu et ici il est nul et produit une erreur.

Fonctions d'assert et d'erreur

Afin de gérer les erreurs, nous utilisons souvent deux fonctions - assert et error. Un exemple simple est présenté ci-dessous.

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)

Lorsque nous exécutons le programme ci-dessus, nous obtenons la sortie d'erreur suivante.

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]: ?

le error (message [, level])met fin à la dernière fonction protégée appelée et renvoie le message comme message d'erreur. Cette erreur de fonction ne revient jamais. En général, l'erreur ajoute des informations sur la position de l'erreur au début du message. L'argument de niveau spécifie comment obtenir la position d'erreur. Avec le niveau 1 (par défaut), la position d'erreur est l'endroit où la fonction d'erreur a été appelée. Le niveau 2 pointe l'erreur vers l'endroit où la fonction qui a appelé error a été appelée; etc. Le passage d'un niveau 0 évite l'ajout d'informations de position d'erreur au message.

pcall et xpcall

En programmation Lua, afin d'éviter de lancer ces erreurs et de gérer les erreurs, nous devons utiliser les fonctions pcall ou xpcall.

le pcall (f, arg1, ...)function appelle la fonction demandée en mode protégé. Si une erreur se produit dans la fonction f, elle ne génère pas d'erreur. Il renvoie simplement le statut d'erreur. Un exemple simple utilisant pcall est présenté ci-dessous.

function myfunction ()
   n = n/nil
end

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

Failure

le xpcall (f, err)function appelle la fonction demandée et définit également le gestionnaire d'erreurs. Toute erreur à l'intérieur de f n'est pas propagée; à la place, xpcall détecte l'erreur, appelle la fonction err avec l'objet d'erreur d'origine et renvoie un code d'état.

Un exemple simple pour xpcall est présenté ci-dessous.

function myfunction ()
   n = n/nil
end

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

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

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

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

En tant que programmeur, il est très important de vous assurer que vous prenez soin de gérer correctement les erreurs dans les programmes que vous écrivez. L'utilisation de la gestion des erreurs peut garantir que les conditions inattendues au-delà des conditions limites sont gérées sans déranger l'utilisateur du programme.

Lua fournit une bibliothèque de débogage, qui fournit toutes les fonctions primitives pour que nous puissions créer notre propre débogueur. Même s'il n'y a pas de débogueur Lua intégré, nous avons de nombreux débogueurs pour Lua, créés par divers développeurs, dont beaucoup sont open source.

The functions available in the Lua debug library are listed in the following table along with its uses.

Sr.No. Method & Purpose
1

debug()

Enters interactive mode for debugging, which remains active till we type in only cont in a line and press enter. User can inspect variables during this mode using other functions.

2

getfenv(object)

Returns the environment of object.

3

gethook(optional thread)

Returns the current hook settings of the thread, as three values − the current hook function, the current hook mask, and the current hook count.

4

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

Returns a table with info about a function. You can give the function directly, or you can give a number as the value of function, which means the function running at level function of the call stack of the given thread − level 0 is the current function (getinfo itself); level 1 is the function that called getinfo; and so on. If function is a number larger than the number of active functions, then getinfo returns nil.

5

getlocal(optional thread, stack level, local index)

Returns the name and the value of the local variable with index local of the function at level of the stack.Returns nil if there is no local variable with the given index, and raises an error when called with a level out of range.

6

getmetatable(value)

Returns the metatable of the given object or nil if it does not have a metatable.

7

getregistry()

Returns the registry table,a pre-defined table that can be used by any C code to store whatever Lua value it needs to store.

8

getupvalue(function, upvalue index)

This function returns the name and the value of the upvalue with index up of the function func. The function returns nil if there is no upvalue with the given index.

9

setfenv(function or thread or userdata, environment table)

Sets the environment of the given object to the given table. Returns object.

10

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

Sets the given function as a hook. The string mask and the number count describes when the hook will be called. Here, c, r and l are called every time Lua calls, returns, and enters every line of code in a function respectively.

11

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

Assigns the value to the local variable with index local of the function at level of the stack. The function returns nil if there is no local variable with the given index, and raises an error when called with a level out of range. Otherwise, it returns the name of the local variable.

12

setmetatable(value, metatable)

Sets the metatable for the given object to the given table (which can be nil).

13

setupvalue(function, upvalue index, value)

This function assigns the value to the upvalue with index up of the function func. The function returns nil if there is no upvalue with the given index. Otherwise, it returns the name of the upvalue.

14

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

Builds an extended error message with a traceback.

The above list is the complete list of debug functions in Lua and we often use a library that uses the above functions and provides easier debugging. Using these functions and creating our own debugger is quite complicated and is not preferable. Anyway, we will see an example of simple use of debugging functions.

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

   return 10
end

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

When we run the above program, we will get the stack trace as shown below.

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

In the above sample program, the stack trace is printed by using the debug.trace function available in the debug library. The debug.getinfo gets the current table of the function.

Debugging - Example

We often need to know the local variables of a function for debugging. For that purpose, we can use getupvalue and to set these local variables, we use setupvalue. A simple example for this is shown below.

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())

When we run the above program, we will get the following output.

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

In this example, the counter updates by one each time it is called. We can see the current state of the local variable using the getupvalue function. We then set the local variable to a new value. Here, n is 2 before the set operation is called. Using setupvalue function, it is updated to 10. Now when we call the counter function, it will return 11 instead of 3.

Debugging Types

  • Command line debugging
  • Graphical debugging

Command Line Debugging

Command line debugging is the type of debugging that uses command line to debug with the help of commands and print statements. There are many command line debuggers available for Lua of which a few are listed below.

  • RemDebug − RemDebug is a remote debugger for Lua 5.0 and 5.1. It lets you control the execution of another Lua program remotely, setting breakpoints and inspecting the current state of the program. RemDebug can also debug CGILua scripts.

  • clidebugger − A simple command line interface debugger for Lua 5.1 written in pure Lua. It's not dependent on anything other than the standard Lua 5.1 libraries. It was inspired by RemDebug but does not have its remote facilities.

  • ctrace − A tool for tracing Lua API calls.

  • xdbLua − A simple Lua command line debugger for the Windows platform.

  • LuaInterface - Debugger − This project is a debugger extension for LuaInterface. It raises the built in Lua debug interface to a higher level. Interaction with the debugger is done by events and method calls.

  • Rldb − This is a remote Lua debugger via socket, available on both Windows and Linux. It can give you much more features than any existing one.

  • ModDebug − This allows in controlling the execution of another Lua program remotely, set breakpoints, and inspect the current state of the program.

Graphical Debugging

Graphical debugging is available with the help of IDE where you are provided with visual debugging of various states like variable values, stack trace and other related information. There is a visual representation and step by step control of execution with the help of breakpoints, step into, step over and other buttons in the IDE.

There are number of graphical debuggers for Lua and it includes the following.

  • SciTE − The default windows IDE for Lua provides multiple debugging facilities like breakpoints, step, step into, step over, watch variables and so on.

  • Decoda − This is a graphical debugger with remote debugging support.

  • ZeroBrane Studio − Lua IDE with integrated remote debugger, stack view, watch view, remote console, static analyzer, and more. Works with LuaJIT, Love2d, Moai, and other Lua engines; Windows, OSX, and Linux. Open source.

  • akdebugger − Debugger and editor Lua plugin for Eclipse.

  • luaedit − This features remote debugging, local debugging, syntax highlighting, completion proposal list, parameter proposition engine, advance breakpoint management (including condition system on breakpoints and hit count), function listing, global and local variables listing, watches, solution oriented management.

Lua uses automatic memory management that uses garbage collection based on certain algorithms that is in-built in Lua. As a result of automatic memory management, as a developer −

  • No need to worry about allocating memory for objects.
  • No need to free them when no longer needed except for setting it to nil.

Lua uses a garbage collector that runs from time to time to collect dead objects when they are no longer accessible from the Lua program.

All objects including tables, userdata, functions, thread, string and so on are subject to automatic memory management. Lua uses incremental mark and sweep collector that uses two numbers to control its garbage collection cycles namely garbage collector pause and garbage collector step multiplier. These values are in percentage and value of 100 is often equal to 1 internally.

Garbage Collector Pause

Garbage collector pause is used for controlling how long the garbage collector needs to wait, before; it is called again by the Lua's automatic memory management. Values less than 100 would mean that Lua will not wait for the next cycle. Similarly, higher values of this value would result in the garbage collector being slow and less aggressive in nature. A value of 200, means that the collector waits for the total memory in use to double before starting a new cycle. Hence, depending on the nature and speed of application, there may be a requirement to alter this value to get best performance in Lua applications.

Garbage Collector Step Multiplier

This step multiplier controls the relative speed of garbage collector to that of memory allocation in Lua program. Larger step values will lead to garbage collector to be more aggressive and it also increases the step size of each incremental step of garbage collection. Values less than 100 could often lead to avoid the garbage collector not to complete its cycle and its not generally preferred. The default value is 200, which means the garbage collector runs twice as the speed of memory allocation.

Garbage Collector Functions

As developers, we do have some control over the automatic memory management in Lua. For this, we have the following methods.

  • collectgarbage("collect") − Runs one complete cycle of garbage collection.

  • collectgarbage("count") − Returns the amount of memory currently used by the program in Kilobytes.

  • collectgarbage("restart") − If the garbage collector has been stopped, it restarts it.

  • collectgarbage("setpause") − Sets the value given as second parameter divided by 100 to the garbage collector pause variable. Its uses are as discussed a little above.

  • collectgarbage("setstepmul") − Sets the value given as second parameter divided by 100 to the garbage step multiplier variable. Its uses are as discussed a little above.

  • collectgarbage("step") − Runs one step of garbage collection. The larger the second argument is, the larger this step will be. The collectgarbage will return true if the triggered step was the last step of a garbage-collection cycle.

  • collectgarbage("stop") − Stops the garbage collector if its running.

A simple example using the garbage collector example is shown below.

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

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("collect"))

print(collectgarbage("count"))

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante. Veuillez noter que ce résultat variera en raison de la différence de type de système d'exploitation et également de la fonction de gestion automatique de la mémoire de Lua.

23.1455078125   149
23.2880859375   295
0
22.37109375     380

Vous pouvez voir dans le programme ci-dessus, une fois que le garbage collection est terminé, il a réduit la mémoire utilisée. Mais ce n'est pas obligatoire d'appeler cela. Même si nous ne les appelons pas, il sera exécuté automatiquement à un stade ultérieur par l'interpréteur Lua après la période prédéfinie.

Évidemment, nous pouvons changer le comportement du garbage collector en utilisant ces fonctions si nécessaire. Ces fonctions fournissent un peu de capacité supplémentaire au développeur pour gérer des situations complexes. Selon le type de mémoire nécessaire pour le programme, vous pouvez ou non utiliser cette fonction. Mais il est très utile de connaître l'utilisation de la mémoire dans les applications et de la vérifier pendant la programmation elle-même pour éviter des résultats indésirables après le déploiement.

Introduction à la POO

La programmation orientée objet (POO) est l'une des techniques de programmation les plus utilisées à l'ère moderne de la programmation. Il existe un certain nombre de langages de programmation prenant en charge la POO, notamment:

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

Caractéristiques de la POO

  • Class - Une classe est un modèle extensible pour créer des objets, fournissant des valeurs initiales pour l'état (variables membres) et des implémentations de comportement.

  • Objects - C'est une instance de classe et a une mémoire distincte allouée pour elle-même.

  • Inheritance - C'est un concept par lequel les variables et les fonctions d'une classe sont héritées par une autre classe.

  • Encapsulation- C'est le processus de combinaison des données et des fonctions à l'intérieur d'une classe. Les données sont accessibles en dehors de la classe à l'aide de fonctions. Il est également connu sous le nom d'abstraction de données.

POO à Lua

Vous pouvez implémenter l'orientation objet dans Lua à l'aide de tables et de fonctions de première classe de Lua. En plaçant des fonctions et des données associées dans une table, un objet est formé. L'héritage peut être implémenté à l'aide de métatables, fournissant un mécanisme de recherche pour les fonctions (méthodes) et les champs inexistants dans les objets parents.

Les tables dans Lua ont les caractéristiques d'objet comme l'état et l'identité qui sont indépendantes de ses valeurs. Deux objets (tables) avec la même valeur sont des objets différents, alors qu'un objet peut avoir des valeurs différentes à des moments différents, mais il s'agit toujours du même objet. Tout comme les objets, les tables ont un cycle de vie indépendant de la personne qui les a créées ou de l'endroit où elles ont été créées.

Un exemple du monde réel

Le concept d'orientation objet est largement utilisé, mais vous devez le comprendre clairement pour un bénéfice approprié et maximal.

Prenons un exemple mathématique simple. Nous rencontrons souvent des situations où nous travaillons sur différentes formes comme le cercle, le rectangle et le carré.

Les formes peuvent avoir une propriété commune. Ainsi, nous pouvons étendre d'autres formes à partir de la forme de l'objet de base avec la zone de propriété commune. Chacune des formes peut avoir ses propres propriétés et des fonctions comme un rectangle peut avoir des propriétés length, width, area comme propriétés et printArea et CalculateArea comme fonctions.

Créer une classe simple

Une implémentation de classe simple pour un rectangle avec trois propriétés area, length et width est illustrée ci-dessous. Il dispose également d'une fonction printArea pour imprimer la zone calculée.

-- 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

Créer un objet

La création d'un objet est le processus d'allocation de mémoire pour l'instance de classe. Chacun des objets a sa propre mémoire et partage les données de classe communes.

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

Accéder aux propriétés

Nous pouvons accéder aux propriétés de la classe en utilisant l'opérateur point comme indiqué ci-dessous -

print(r.length)

Accès à la fonction membre

Vous pouvez accéder à une fonction membre en utilisant l'opérateur deux-points avec l'objet comme indiqué ci-dessous -

r:printArea()

La mémoire est allouée et les valeurs initiales sont définies. Le processus d'initialisation peut être comparé à des constructeurs dans d'autres langages orientés objet. Ce n'est rien d'autre qu'une fonction qui permet de définir des valeurs comme indiqué ci-dessus.

Exemple complet

Regardons un exemple complet utilisant l'orientation objet dans 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()

Lorsque vous exécutez le programme ci-dessus, vous obtiendrez la sortie suivante.

The area is 	100

Héritage à Lua

L'héritage est le processus consistant à étendre des objets de base simples comme la forme à des rectangles, des carrés, etc. Il est souvent utilisé dans le monde réel pour partager et étendre les propriétés et fonctions de base.

Voyons une simple extension de classe. Nous avons une classe comme indiqué ci-dessous.

-- 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

Nous pouvons étendre la forme à une classe carrée comme indiqué ci-dessous.

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

Fonctions de base de dépassement

Nous pouvons remplacer les fonctions de classe de base qui sont au lieu d'utiliser la fonction dans la classe de base, la classe dérivée peut avoir sa propre implémentation comme indiqué ci-dessous -

-- Derived class method printArea

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

Exemple d'héritage complet

Nous pouvons étendre l'implémentation de classe simple dans Lua comme indiqué ci-dessus à l'aide d'une autre nouvelle méthode à l'aide de métatables. Toutes les variables membres et fonctions de la classe de base sont conservées dans la classe dérivée.

-- 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()

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante -

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

Dans l'exemple ci-dessus, nous avons créé deux classes dérivées - Rectangle et Square à partir de la classe de base Square. Il est possible de remplacer les fonctions de la classe de base dans la classe dérivée. Dans cet exemple, la classe dérivée remplace la fonction printArea.

Lua est un langage très flexible et il est souvent utilisé dans plusieurs plates-formes, y compris des applications Web. La communauté Kepler qui a été formée en 2004 pour fournir des composants Web open source en Lua.

Même s'il existe d'autres frameworks Web utilisant Lua qui ont été développés, nous nous concentrerons principalement sur les composants fournis par la communauté Kepler.

Applications et cadres

  • Orbit est un framework Web MVC pour Lua, basé sur WSAPI.

  • WSAPI est l'API qui extrait le serveur hôte Web des applications Web Lua et constitue la base de nombreux projets.

  • Xavante est un serveur Web Lua qui offre une interface WSAPI.

  • Sputnik est un wiki / CMS développé sur WSAPI sur Kepler Project utilisé pour l'humour et le divertissement.

  • CGILuapropose la création de pages Web LuaPages et LuaScripts, basée sur WSAPI mais qui n'est plus prise en charge. Utilisez plutôt Orbit, Sputnik ou WSAPI.

Dans ce tutoriel, nous allons essayer de vous faire comprendre ce que Lua peut faire et pour en savoir plus sur son installation et son utilisation, reportez-vous au site kepler

Orbite

Orbit est un framework Web MVC pour Lua. Il abandonne complètement le modèle CGILua des «scripts» au profit des applications, où chaque application Orbit peut tenir dans un seul fichier, mais vous pouvez le diviser en plusieurs fichiers si vous le souhaitez.

Toutes les applications Orbit suivent le protocole WSAPI, elles fonctionnent donc actuellement avec Xavante, CGI et Fastcgi. Il comprend un lanceur qui facilite le lancement d'une instance Xavante pour le développement.

Le moyen le plus simple d'installer Orbit est d'utiliser LuaRocks. Luarocks install orbit est la commande pour l'installation. Pour cela, vous devez d'abord installer LuaRocks .

Si vous n'avez pas installé toutes les dépendances, voici les étapes à suivre pour configurer Orbit dans un environnement Unix / Linux.

Installer Apache

Connectez-vous à votre serveur. Installez Apache2, ses modules de support et activez les modules Apache2 requis en utilisant -

$ 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

Installez LuaRocks

$ sudo apt-get install luarocks

Installez WSAPI, FCGI, Orbit et Xavante

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

Configurer Apache2

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

Ajoutez cette section suivante sous la section <Directory / var / www /> du fichier de configuration. Si cette section a un 'AllowOverride None' alors vous devez changer le 'None' en 'All' afin que le fichier .htaccess puisse remplacer la configuration localement.

<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>

Redémarrez le serveur pour vous assurer que les modifications apportées prennent effet.

Pour activer votre application, vous devez ajouter + ExecCGI à un fichier .htaccess à la racine de votre application Orbit - dans ce cas, / var / www.

Options +ExecCGI
DirectoryIndex index.ws

Exemple simple - Orbite

#!/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

Vous devriez maintenant pouvoir lancer votre navigateur Web. Accédez à http: // localhost: 8080 / et vous devriez voir la sortie suivante -

First Page

Orbit fournit une autre option, c'est-à-dire que le code Lua peut générer du 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())

Créer des formulaires

Un exemple de formulaire simple est présenté ci-dessous -

#!/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

Comme mentionné précédemment, WSAPI sert de base à de nombreux projets et intègre plusieurs fonctionnalités. Vous pouvez utiliser WSAPI et prendre en charge les plates-formes suivantes,

  • Windows
  • Systèmes basés sur UNIX

Les serveurs et interfaces pris en charge par WSAPI comprennent,

  • CGI
  • FastCGI
  • Xavante

WSAPI fournit un certain nombre de bibliothèques, ce qui nous facilite la tâche dans la programmation Web à l'aide de Lua. Certaines des fonctionnalités prises en charge dans Lua comprennent,

  • Traitement de la demande
  • Tampon de sortie
  • Authentication
  • Téléchargements de fichiers
  • Demander l'isolement
  • Multiplexing

Un exemple simple de WSAPI est présenté ci-dessous -

#!/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

Vous pouvez voir dans le code ci-dessus qu'une simple page html est formée et renvoyée. Vous pouvez voir l'utilisation des coroutines qui permet de renvoyer instruction par instruction à la fonction appelante. Enfin, le code d'état html (200), les en-têtes et la page html sont renvoyés.

Xavante

Xavante est un serveur Web Lua HTTP 1.1 qui utilise une architecture modulaire basée sur des gestionnaires mappés par URI. Xavante propose actuellement,

  • Gestionnaire de fichiers
  • Gestionnaire de redirection
  • Gestionnaire WSAPI

Le gestionnaire de fichiers est utilisé pour les fichiers généraux. Le gestionnaire de redirection active le remappage d'URI et le gestionnaire WSAPI pour la gestion des applications WSAPI.

Un exemple simple est présenté ci-dessous.

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
   },
}

Pour utiliser des hôtes virtuels avec Xavante, l'appel à xavante.HTTP serait changé en quelque chose comme suit -

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

Composants Web Lua

  • Copas, un répartiteur basé sur des coroutines utilisables par les serveurs TCP / IP.

  • Cosmo, un moteur de "modèles sûrs" qui protège votre application du code arbitraire dans les modèles.

  • Coxpcall encapsule pcall natif Lua et xpcall avec ceux compatibles coroutine.

  • LuaFileSystem, un moyen portable d'accéder à la structure de répertoire et aux attributs de fichier sous-jacents.

  • Rings, une bibliothèque qui permet de créer de nouveaux états Lua à partir de Lua.

Note de fin

Il y a tellement de frameworks et de composants Web basés sur Lua disponibles pour nous et en fonction des besoins, ils peuvent être choisis. Il existe d'autres frameworks Web disponibles, notamment:

  • Moonstalkpermet le développement et l'hébergement efficaces de projets Web générés dynamiquement et construits avec le langage Lua; des pages basiques aux applications complexes.

  • Lapis, un framework pour créer des applications Web à l'aide de MoonScript (ou Lua) qui s'exécute dans une version personnalisée de Nginx appelée OpenResty.

  • Lua Server Pages, un plug-in de moteur de script Lua qui supprime toute autre approche du développement Web intégré, offre un raccourci spectaculaire vers les pages de serveur C traditionnelles.

Ces frameworks Web peuvent exploiter vos applications Web et vous aider à effectuer des opérations puissantes.

Pour les opérations de données simples, nous pouvons utiliser des fichiers, mais, parfois, ces opérations sur les fichiers peuvent ne pas être efficaces, évolutives et puissantes. Pour cela, nous pouvons souvent passer à l'utilisation de bases de données. LuaSQL est une interface simple de Lua vers un certain nombre de systèmes de gestion de bases de données. LuaSQL est la bibliothèque qui prend en charge différents types de SQL. Cela comprend,

  • SQLite
  • Mysql
  • ODBC

Dans ce tutoriel, nous couvrirons la gestion des bases de données de MySQL et SQLite en Lua. Cela utilise une interface générique pour les deux et devrait également être possible de porter cette implémentation vers d'autres types de bases de données. Voyons d'abord comment vous pouvez effectuer les opérations dans MySQL.

Configuration de la base de données MySQL

Pour que les exemples suivants fonctionnent comme prévu, nous avons besoin de la configuration initiale de la base de données. Les hypothèses sont énumérées ci-dessous.

  • Vous avez installé et configuré MySQL avec l'utilisateur par défaut comme root et le mot de passe comme «123456».

  • Vous avez créé un test de base de données.

  • Vous avez parcouru le didacticiel MySQL pour comprendre les bases de MySQL.

Importer MySQL

Nous pouvons utiliser un simple require pour importer la bibliothèque sqlite en supposant que votre implémentation Lua a été effectuée correctement.

mysql = require "luasql.mysql"

La variable mysql donnera accès aux fonctions en se référant à la table principale mysql.

Configuration de la connexion

Nous pouvons configurer la connexion en lançant un environnement MySQL puis en créant une connexion pour l'environnement. Il est montré ci-dessous.

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

La connexion ci-dessus se connectera à un fichier MySQL existant et établira la connexion avec le fichier nouvellement créé.

Exécuter la fonction

Il y a une fonction d'exécution simple disponible avec la connexion qui nous aidera à faire toutes les opérations de base de données de créer, insérer, supprimer, mettre à jour et ainsi de suite. La syntaxe est indiquée ci-dessous -

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

Dans la syntaxe ci-dessus, nous devons nous assurer que conn est ouvert et que la connexion MySQL existe et remplacer «MySQLSTATEMENT» par l'instruction correcte.

Créer un exemple de table

Un exemple simple de création de table est présenté ci-dessous. Il crée une table avec deux paramètres id de type integer et nom de type 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 )

Lorsque vous exécutez le programme ci-dessus, une table nommée sample sera créée avec deux colonnes à savoir, id et name.

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

En cas d'erreur, vous recevrez une instruction d'erreur au lieu de nil. Une simple déclaration d'erreur est présentée ci-dessous.

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

Insérer un exemple de déclaration

Une instruction d'insertion pour MySQL est présentée ci-dessous.

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

Exemple de déclaration de mise à jour

Une instruction de mise à jour pour MySQL est présentée ci-dessous.

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

Exemple d'instruction de suppression

Une instruction de suppression pour MySQL est présentée ci-dessous.

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

Sélectionnez un exemple de déclaration

En ce qui concerne l'instruction select, nous devons parcourir chacune des lignes et extraire les données requises. Une instruction de sélection simple est présentée ci-dessous.

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

Dans le code ci-dessus, conn est une connexion MySQL ouverte. À l'aide du curseur renvoyé par l'instruction d'exécution, vous pouvez parcourir la réponse de la table et récupérer les données de sélection requises.

Un exemple complet

Un exemple complet comprenant toutes les déclarations ci-dessus est donné ci-dessous.

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()

Lorsque vous exécutez le programme ci-dessus, vous obtiendrez la sortie suivante.

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

Effectuer des transactions

Les transactions sont un mécanisme qui garantit la cohérence des données. Les transactions doivent avoir les quatre propriétés suivantes -

  • Atomicity - Soit une transaction se termine, soit rien ne se passe du tout.

  • Consistency - Une transaction doit démarrer dans un état cohérent et laisser le système dans un état cohérent.

  • Isolation - Les résultats intermédiaires d'une transaction ne sont pas visibles en dehors de la transaction en cours.

  • Durability - Une fois qu'une transaction a été validée, les effets sont persistants, même après une panne du système.

La transaction commence par START TRANSACTION; et se termine par une instruction de validation ou d'annulation.

Commencer la transaction

Afin d'initier une transaction, nous devons exécuter l'instruction suivante en Lua, en supposant que conn est une connexion MySQL ouverte.

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

Transaction d'annulation

Nous devons exécuter l'instruction suivante pour annuler les modifications apportées après l'exécution de la transaction de démarrage.

conn:execute([[ROLLBACK;]])

Valider la transaction

Nous devons exécuter l'instruction suivante pour valider les modifications apportées après l'exécution de la transaction de démarrage.

conn:execute([[COMMIT;]])

Nous avons connu MySQL dans la section ci-dessus et la section suivante explique les opérations SQL de base. Rappelez-vous les transactions, bien que cela ne soit pas expliqué à nouveau pour SQLite3, mais les mêmes instructions devraient également fonctionner pour SQLite3.

Importer SQLite

Nous pouvons utiliser une simple instruction require pour importer la bibliothèque SQLite en supposant que votre implémentation Lua a été effectuée correctement. Lors de l'installation, un dossier libsql contenant les fichiers liés à la base de données.

sqlite3 = require "luasql.sqlite3"

La variable sqlite3 donnera accès aux fonctions en se référant à la table principale sqlite3.

Configuration de la connexion

Nous pouvons configurer la connexion en lançant un environnement SQLite, puis en créant une connexion pour l'environnement. Il est montré ci-dessous.

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

La connexion ci-dessus se connecte à un fichier SQLite existant ou crée un nouveau fichier SQLite et établit la connexion avec le fichier nouvellement créé.

Exécuter la fonction

Il y a une fonction d'exécution simple disponible avec la connexion qui nous aidera à faire toutes les opérations de base de données de créer, insérer, supprimer, mettre à jour et ainsi de suite. La syntaxe est indiquée ci-dessous -

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

Dans la syntaxe ci-dessus, nous devons nous assurer que conn est ouvert et que la connexion sqlite3 existe et remplacer «SQLite3STATEMENT» par l'instruction correcte.

Créer un exemple de table

Un exemple simple de création de table est présenté ci-dessous. Il crée une table avec deux paramètres id de type integer et nom de type 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 )

Lorsque vous exécutez le programme ci-dessus, une table nommée sample sera créée avec deux colonnes à savoir, id et name.

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

En cas d'erreur, vous recevrez une instruction d'erreur au lieu de nil. Une simple déclaration d'erreur est présentée ci-dessous.

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

Insérer un exemple de déclaration

Une instruction d'insertion pour SQLite est présentée ci-dessous.

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

Sélectionnez un exemple de déclaration

En ce qui concerne l'instruction select, nous devons parcourir chacune des lignes et extraire les données requises. Une instruction de sélection simple est présentée ci-dessous.

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

Dans le code ci-dessus, conn est une connexion sqlite3 ouverte. À l'aide du curseur renvoyé par l'instruction d'exécution, vous pouvez parcourir la réponse de la table et récupérer les données de sélection requises.

Un exemple complet

Un exemple complet comprenant toutes les déclarations ci-dessus est donné ci-dessous.

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()

Lorsque vous exécutez le programme ci-dessus, vous obtiendrez la sortie suivante.

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

Nous pouvons exécuter toutes les requêtes disponibles à l'aide de cette bibliothèque libsql. Alors, ne vous arrêtez pas avec ces exemples. Expérimentez diverses instructions de requête disponibles dans MySQL, SQLite3 et autres bases de données prises en charge dans Lua.

Lua est utilisé dans de nombreux moteurs de jeu en raison de sa structure de langage et de sa syntaxe simples. La fonction de récupération de place est souvent très utile dans les jeux qui consomment beaucoup de mémoire en raison de la richesse des graphiques utilisés. Certains moteurs de jeu qui utilisent Lua incluent -

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

Chacun de ces moteurs de jeu est basé sur Lua et il existe un riche ensemble d'API disponibles dans chacun de ces moteurs. Nous examinerons brièvement les capacités de chacun.

SDK Corona

Corona SDK est un moteur de jeu mobile multiplateforme qui prend en charge les plates-formes iPhone, iPad et Android. Il existe une version gratuite du SDK Corona qui peut être utilisée pour les petits jeux avec des fonctionnalités limitées. Vous pouvez mettre à niveau vers d'autres versions si nécessaire.

Corona SDK fournit un certain nombre de fonctionnalités, notamment:

  • API de physique et de gestion des collisions
  • API Web et réseau
  • API Game Network
  • API Ads
  • API Analytics
  • API de base de données et de système de fichiers
  • API cryptographiques et mathématiques
  • API audio et multimédia

Il est plus facile et plus rapide de développer une application à l'aide des API ci-dessus plutôt que d'utiliser les API natives séparément pour iOS et Android.

Gideros Mobile

Gideros fournit le SDK multiplateforme pour créer des jeux pour iOS et Android. Il est gratuit à utiliser avec un splash made with Gideros. Certains des avantages frappants de Gideoros comprennent:

  • Development IDE - Il fournit son propre IDE qui facilite le développement d'applications Gideros.

  • Instant testing- Lors du développement de votre jeu, il peut être testé sur un appareil réel via Wifi en seulement 1 seconde. Vous n'avez pas besoin de perdre votre temps avec un processus d'exportation ou de déploiement.

  • Plugins- Vous pouvez facilement étendre le noyau avec des plugins. Importez votre code existant (C, C ++, Java ou Obj-C), liez-le à Lua et interprétez-le directement. Des dizaines de plugins open source sont déjà développés et prêts à être utilisés.

  • Clean OOP approach - Gideros fournit son propre système de classes avec toutes les normes de base de la POO, vous permettant d'écrire du code propre et réutilisable pour n'importe lequel de vos futurs jeux.

  • Native speed - Développé au-dessus de C / C ++ et OpenGL, votre jeu fonctionne à une vitesse native et utilise pleinement la puissance des processeurs et des GPU en dessous.

ShiVa3D

ShiVa3D est l'un des moteurs de jeux 3D qui fournit un éditeur graphique conçu pour créer des applications et des jeux vidéo pour le Web, les consoles et les appareils mobiles. Il prend en charge plusieurs plates-formes, notamment Windows, Mac, Linux, iOS, Android, BlackBerry, Palm OS, Wii et WebOS.

Certaines des principales caractéristiques comprennent

  • Plugins standards
  • API de modification de maillage
  • IDE
  • Éditeur de terrain, d'océan et d'animation intégré
  • Prise en charge du moteur physique ODE
  • Contrôle complet de la lightmap
  • Aperçu en direct des matériaux, des particules, des traînées et des HUD
  • Prise en charge du format d'échange Collada

L'édition Web de Shiva3d est entièrement gratuite et d'autres éditions vous sont abonnées.

SDK Moai

Moai SDK est un moteur de jeu mobile multiplateforme qui prend en charge les plates-formes iPhone, iPad et Android. La plate-forme Moai était initialement composée de Moai SDK, un moteur de jeu open source, et de Moai Cloud, une plate-forme cloud en tant que service pour l'hébergement et le déploiement de services de jeux. Maintenant, le Moai Cloud est arrêté et seul le moteur de jeu est disponible.

Moai SDK fonctionne sur plusieurs plates-formes, notamment iOS, Android, Chrome, Windows, Mac et Linux.

L'AMOUR

LOVE est un framework que vous pouvez utiliser pour créer des jeux 2D. C'est gratuit et open-source. Il prend en charge les plates-formes Windows, Mac OS X et Linux.

Il fournit plusieurs fonctionnalités qui incluent,

  • API audio
  • API du système de fichiers
  • API du clavier et du joystick
  • API mathématique
  • API de fenêtre et de souris
  • API de physique
  • API système et minuterie

CryEngine

CryEngine est un moteur de jeu développé par le développeur de jeux allemand Crytek. Il a évolué de la génération 1 à la génération 4 et est une solution de développement avancée. Il prend en charge les jeux PC, Xbox 360, PlayStation3 et WiiU.

Il fournit plusieurs fonctionnalités qui incluent,

  • Effets visuels tels que l'éclairage naturel et les ombres douces dynamiques, l'éclairage global dynamique en temps réel, le volume de propagation de la lumière, l'ombrage des particules, la tessellation, etc.

  • Système d'animation de personnage et système d'individualisation de personnage.

  • Animation squelettique paramétrique et éditeur d'animation faciale dédié unique

  • Systèmes d'IA tels que le maillage de navigation multicouche et le système de points tactiques. Fournit également un système d'édition AI convivial pour les concepteurs.

  • Dans le mixage et le profilage de jeu, les sons dynamiques du système sonore piloté par les données et la musique interactive, etc.

  • Caractéristiques physiques telles que la déformation procédurale et la physique avancée des cordes.

Une note de fin

Chacun de ces SDK / frameworks de jeu a ses propres avantages et inconvénients. Un bon choix entre eux facilite votre tâche et vous permet de passer un meilleur moment. Donc, avant de l'utiliser, vous devez connaître les exigences de votre jeu, puis analyser ce qui répond à tous vos besoins et ensuite les utiliser.

Les bibliothèques standard Lua fournissent un ensemble riche de fonctions qui sont implémentées directement avec l'API C et sont intégrées au langage de programmation Lua. Ces bibliothèques fournissent des services dans le langage de programmation Lua et également des services extérieurs tels que les opérations de fichiers et de bases de données.

Ces bibliothèques standard intégrées à l'API C officielle sont fournies sous forme de modules C séparés. Il comprend les éléments suivants -

  • Bibliothèque de base, qui comprend la sous-bibliothèque coroutine
  • Bibliothèque de modules
  • Manipulation des cordes
  • Manipulation de table
  • Bibliothèque de mathématiques
  • Entrée et sortie de fichier
  • Installations du système d'exploitation
  • Installations de débogage

Bibliothèque de base

Nous avons utilisé la bibliothèque de base tout au long du didacticiel sous divers sujets. Le tableau suivant fournit des liens vers des pages associées et répertorie les fonctions qui sont couvertes dans diverses parties de ce didacticiel Lua.

Sr.No. Bibliothèque / méthode et objectif
1

Error Handling

Inclut des fonctions de gestion des erreurs comme assert, error comme expliqué dans Lua - Error Handling .

2

Memory Management

Inclut les fonctions de gestion automatique de la mémoire liées au garbage collection comme expliqué dans Lua - Garbage Collection .

3

dofile ([filename])

Il ouvre le fichier et exécute le contenu du fichier comme un morceau. Si aucun paramètre n'est passé, cette fonction exécute le contenu de l'entrée standard. Les erreurs seront propagées à l'appelant.

4

_G

Ainsi est la variable globale qui contient l'environnement global (c'est-à-dire _G._G = _G). Lua elle-même n'utilise pas cette variable.

5

getfenv ([f])

Renvoie l'environnement actuel utilisé par la fonction. f peut être une fonction Lua ou un nombre qui spécifie la fonction à ce niveau de pile - Le niveau 1 est la fonction appelant getfenv. Si la fonction donnée n'est pas une fonction Lua, ou si f vaut 0, getfenv renvoie l'environnement global. La valeur par défaut pour f est 1.

6

getmetatable (object)

Si l'objet n'a pas de métatable, renvoie nil. Sinon, si la métatable de l'objet a un champ «__metatable», renvoie la valeur associée. Sinon, retourne la métatable de l'objet donné.

sept

ipairs (t)

Cette fonction récupère les indices et les valeurs des tables.

8

load (func [, chunkname])

Charge un morceau en utilisant la fonction func pour obtenir ses morceaux. Chaque appel à func doit renvoyer une chaîne concaténée avec les résultats précédents.

9

loadfile ([filename]))

Similaire à load, mais récupère le morceau à partir du nom de fichier du fichier ou de l'entrée standard, si aucun nom de fichier n'est donné.

dix

loadstring (string [, chunkname])

Similaire à load, mais récupère le morceau de la chaîne donnée.

11

next (table [, index])

Permet à un programme de parcourir tous les champs d'une table. Son premier argument est une table et son second argument est un index de cette table. next renvoie l'index suivant de la table et sa valeur associée.

12

pairs (t)

Suspend la coroutine en cours d'exécution. Le paramètre passé à cette méthode agit comme des valeurs de retour supplémentaires pour la fonction de reprise.

13

print (...)

Suspend la coroutine en cours d'exécution. Le paramètre passé à cette méthode agit comme des valeurs de retour supplémentaires pour la fonction de reprise.

14

rawequal (v1, v2)

Vérifie si v1 est égal à v2, sans invoquer de métaméthode. Renvoie un booléen.

15

rawget (table, index)

Obtient la valeur réelle de table [index], sans appeler de métaméthode. la table doit être une table; index peut être n'importe quelle valeur.

16

rawset (table, index, value)

Définit la valeur réelle de table [index] sur value, sans invoquer de métaméthode. table doit être une table, indexer toute valeur différente de nil et valoriser toute valeur Lua. Cette fonction renvoie une table.

17

select (index, ...)

Si index est un nombre, renvoie tous les arguments après le numéro d'argument index. Sinon, index doit être la chaîne "#" et select renvoie le nombre total d'arguments supplémentaires reçus.

18

setfenv (f, table)

Définit l'environnement à utiliser par la fonction donnée. f peut être une fonction Lua ou un nombre qui spécifie la fonction à ce niveau de pile - Le niveau 1 est la fonction appelant setfenv. setfenv renvoie la fonction donnée. Dans un cas particulier, lorsque f vaut 0, setfenv modifie l'environnement du thread en cours d'exécution. Dans ce cas, setfenv ne renvoie aucune valeur.

19

setmetatable (table, metatable)

Définit la métatable pour la table donnée. (Vous ne pouvez pas modifier la métatable d'autres types à partir de Lua, uniquement à partir de C.) Si métatable est nul, supprime la métatable de la table donnée. Si le métatable d'origine a un champ «__metatable», génère une erreur. Cette fonction renvoie une table.

20

tonumber (e [, base])

Tente de convertir son argument en nombre. Si l'argument est déjà un nombre ou une chaîne convertible en nombre, alors tonumber renvoie ce nombre; sinon, il renvoie nul.

21

tostring (e)

Reçoit un argument de n'importe quel type et le convertit en une chaîne dans un format raisonnable. Pour un contrôle complet de la façon dont les nombres sont convertis, utilisez string.format.

22

type (v)

Renvoie le type de son seul argument, codé sous forme de chaîne. Les résultats possibles de cette fonction sont "nil" (une chaîne, pas la valeur nil), "number", "string", "boolean", "table", "function", "thread" et "userdata".

23

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

Renvoie les éléments de la table donnée.

24

_VERSION

Une variable globale (pas une fonction) qui contient une chaîne contenant la version actuelle de l'interpréteur. Le contenu actuel de cette variable est "Lua 5.1".

25

Coroutines

Inclut les fonctions de manipulation de coroutine comme expliqué dans Lua - Coroutines .

Bibliothèque de modules

La bibliothèque de modules fournit les fonctions de base pour le chargement de modules dans Lua. Il exporte une fonction directement dans l'environnement global: require. Tout le reste est exporté dans un package de table. Les détails sur la bibliothèque de modules sont expliqués dans le chapitre précédent Lua - Tutoriel Modules .

Manipulation des cordes

Lua fournit un riche ensemble de fonctions de manipulation de chaînes. Le précédent didacticiel Lua - Strings couvre cela en détail.

Manipulation de table

Lua dépend des tables dans presque chaque partie de ses opérations. Le précédent didacticiel Lua - Tables couvre cela en détail.

Entrée et sortie de fichier

Nous avons souvent besoin d'une installation de stockage de données dans la programmation et cela est fourni par les fonctions de bibliothèque standard pour les E / S de fichiers dans Lua. Il est abordé dans le précédent didacticiel Lua - File I / O.

Installations de débogage

Lua fournit une bibliothèque de débogage qui fournit toutes les fonctions primitives pour que nous puissions créer notre propre débogueur. Il est abordé dans le didacticiel de débogage Lua précédent .

Nous avons souvent besoin d'opérations mathématiques dans les calculs scientifiques et d'ingénierie et nous pouvons en profiter en utilisant les mathématiques standard de la bibliothèque Lua. La liste des fonctions disponibles dans la bibliothèque mathématique est présentée dans le tableau suivant.

Sr.No. Bibliothèque / méthode et objectif
1

math.abs (x)

Renvoie la valeur absolue de x.

2

math.acos (x)

Renvoie l'arc cosinus de x (en radians).

3

math.asin (x)

Renvoie l'arc sinus de x (en radians).

4

math.atan (x)

Renvoie l'arc tangent de x (en radians).

5

math.atan2 (y, x)

Renvoie l'arc tangent de y / x (en radians), mais utilise les signes des deux paramètres pour trouver le quadrant du résultat. (Il gère également correctement le cas où x est égal à zéro.)

6

math.ceil (x)

Renvoie le plus petit entier supérieur ou égal à x.

sept

math.cos (x)

Renvoie le cosinus de x (supposé être en radians).

8

math.cosh (x)

Renvoie le cosinus hyperbolique de x.

9

math.deg (x)

Renvoie l'angle x (exprimé en radians) en degrés.

dix

math.exp (x)

Renvoie la valeur e puissance x.

11

math.floor (x)

Renvoie le plus grand entier inférieur ou égal à x.

12

math.fmod (x, y)

Renvoie le reste de la division de x par y qui arrondit le quotient vers zéro.

13

math.frexp (x)

Renvoie m et e tels que x = m2e, e est un entier et la valeur absolue de m est dans la plage [0,5, 1) (ou zéro lorsque x vaut zéro).

14

math.huge

La valeur HUGE_VAL, une valeur supérieure ou égale à toute autre valeur numérique.

15

math.ldexp (m, e)

Renvoie m2e (e doit être un entier).

16

math.log (x)

Renvoie le logarithme naturel de x.

17

math.log10 (x)

Renvoie le logarithme en base 10 de x.

18

math.max (x, ...)

Renvoie la valeur maximale parmi ses arguments.

19

math.min (x, ...)

Renvoie la valeur minimale parmi ses arguments.

20

math.modf (x)

Renvoie deux nombres, la partie intégrale de x et la partie fractionnaire de x.

21

math.pi

La valeur de pi.

22

math.pow (x, y)

Renvoie xy. (Vous pouvez également utiliser l'expression x ^ y pour calculer cette valeur.)

23

math.rad (x)

Renvoie l'angle x (exprimé en degrés) en radians.

24

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

Cette fonction est une interface avec la fonction de générateur pseudo-aléatoire simple rand fournie par ANSI C. Lorsqu'elle est appelée sans argument, renvoie un nombre réel pseudo-aléatoire uniforme dans la plage [0,1). Lorsqu'il est appelé avec un nombre entier m, math.random renvoie un entier pseudo-aléatoire uniforme dans la plage [1, m]. Lorsqu'il est appelé avec deux nombres entiers m et n, math.random renvoie un entier pseudo-aléatoire uniforme dans la plage [m, n].

25

math.randomseed (x)

Définit x comme "graine" pour le générateur pseudo-aléatoire: des graines égales produisent des séquences égales de nombres.

26

math.sin (x)

Renvoie le sinus de x (supposé être en radians).

27

math.sinh (x)

Renvoie le sinus hyperbolique de x.

28

math.sqrt (x)

Renvoie la racine carrée de x. (Vous pouvez également utiliser l'expression x ^ 0.5 pour calculer cette valeur.)

29

math.tan (x)

Renvoie la tangente de x (supposée être en radians).

30

math.tanh (x)

Renvoie la tangente hyperbolique de x.

Fonctions trigonométriques

Un exemple simple utilisant la fonction trigonométrique est présenté ci-dessous.

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")

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

0.027415567780804
0.0 
1.0 
0.0 
1.0 
180

Autres fonctions mathématiques courantes

Un exemple simple utilisant des fonctions mathématiques courantes est présenté ci-dessous.

-- 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")

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante.

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

Les exemples ci-dessus ne sont que quelques-uns des exemples courants, nous pouvons utiliser une bibliothèque mathématique en fonction de nos besoins, essayez donc d'utiliser toutes les fonctions pour être plus familier.

Dans toute application, il est souvent nécessaire pour accéder aux fonctions de niveau du système d'exploitation et il est disponible avec la bibliothèque du système d'exploitation. La liste des fonctions disponibles est répertoriée dans le tableau suivant.

Sr.No. Bibliothèque / méthode et objectif
1

os.clock ()

Renvoie une approximation de la quantité en secondes de temps CPU utilisé par le programme.

2

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

Renvoie une chaîne ou un tableau contenant la date et l'heure, formatés selon le format de chaîne donné.

3

os.difftime (t2, t1)

Renvoie le nombre de secondes entre l'instant t1 et l'instant t2. Dans POSIX, Windows et certains autres systèmes, cette valeur est exactement t2-t1.

4

os.execute ([command])

Cette fonction est équivalente au système de fonction ANSI C. Il transmet la commande à exécuter par un shell du système d'exploitation. Son premier résultat est vrai si la commande s'est terminée correctement, ou nul dans le cas contraire.

5

os.exit ([code [, close])

Appelle la sortie de la fonction ANSI C pour terminer le programme hôte. Si le code est vrai, l'état renvoyé est EXIT_SUCCESS; si le code est faux, l'état renvoyé est EXIT_FAILURE; si le code est un nombre, l'état renvoyé est ce nombre.

6

os.getenv (varname)

Renvoie la valeur de la variable d'environnement de processus varname, ou nil si la variable n'est pas définie.

sept

os.remove (filename)

Supprime le fichier (ou le répertoire vide, sur les systèmes POSIX) avec le nom donné. Si cette fonction échoue, elle renvoie nil, plus une chaîne décrivant l'erreur et le code d'erreur.

8

os.rename (oldname, newname)

Renomme le fichier ou le répertoire nommé oldname en newname. Si cette fonction échoue, elle renvoie nil, plus une chaîne décrivant l'erreur et le code d'erreur.

9

os.setlocale (locale [, category])

Définit les paramètres régionaux actuels du programme. locale est une chaîne dépendant du système spécifiant une locale; category est une chaîne facultative décrivant la catégorie à modifier: "all", "collate", "ctype", "money", "numeric" ou "time"; la catégorie par défaut est "tous". La fonction renvoie le nom de la nouvelle locale, ou nil si la demande ne peut pas être honorée.

dix

os.time ([table])

Renvoie l'heure actuelle lorsqu'elle est appelée sans arguments, ou une heure représentant la date et l'heure spécifiées par la table donnée. Cette table doit avoir des champs année, mois et jour, et peut avoir des champs heure (la valeur par défaut est 12), min (la valeur par défaut est 0), sec (la valeur par défaut est 0) et isdst (la valeur par défaut est nulle). Pour une description de ces champs, consultez la fonction os.date.

11

os.tmpname ()

Renvoie une chaîne avec un nom de fichier pouvant être utilisé pour un fichier temporaire. Le fichier doit être ouvert explicitement avant son utilisation et explicitement supprimé lorsqu'il n'est plus nécessaire.

Fonctions OS communes

Un exemple simple utilisant des fonctions mathématiques courantes est présenté ci-dessous.

-- 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")

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons une sortie similaire à la suivante.

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

Les exemples ci-dessus ne sont que quelques-uns des exemples courants, nous pouvons utiliser la bibliothèque du système d'exploitation en fonction de nos besoins, alors essayez d'utiliser toutes les fonctions pour être plus familier. Il existe des fonctions comme remove qui aide à supprimer le fichier, exécuter qui nous aide à exécuter les commandes du système d'exploitation comme expliqué ci-dessus.