LuaDémarrer avec Lua


Remarques

Logo Lua

Lua est un langage de script minimaliste, léger et intégrable. Il est conçu, mis en œuvre et entretenu par une équipe de PUC-Rio , l'Université pontificale catholique de Rio de Janeiro au Brésil. La liste de diffusion est ouverte pour participer.

Les cas d'utilisation courants de Lua incluent les jeux vidéo de script, l'extension d'applications avec des plugins et des configs, l'intégration d'une logique métier de haut niveau ou l'intégration dans des périphériques tels que des téléviseurs, des voitures, etc.

Pour les tâches à hautes performances, il existe une implémentation indépendante utilisant un compilateur juste-à-temps, appelé LuaJIT .

Versions

Version Remarques Date de sortie
1.0 Version initiale, non publique. 1993-07-28
1.1 Première version publique. Document de conférence le décrivant. 1994-07-08
2.1 À partir de Lua 2.1, Lua est devenu librement disponible pour toutes les utilisations, y compris commerciales. Journal de journal le décrivant. 1995-02-07
2.2 Chaînes longues, interface de débogage, meilleure traçabilité des piles 1995-11-28
2.4 Compilateur luac externe 1996-05-14
2,5 Correspondance de modèle et fonctions vararg. 1996-11-19
3.0 Introduit auxlib, une bibliothèque d'aide à l'écriture des bibliothèques Lua 1997-07-01
3.1 Fonctions anonymes et fermetures de fonctions via "upvalues". 1998-07-11
3.2 Bibliothèque de débogage et nouvelles fonctions de table 1999-07-08
3.2.2 2000-02-22
4.0 États multiples, instructions "for", modification de l'API. 2000-11-06
4.0.1 2002-07-04
5.0 Les coroutines, les métabalises, la portée lexicale complète, les appels de queue, les booléens passent à la licence MIT. 2003-04-11
5.0.3 2006-06-26
5.1 Réorganisation du système de modules, récupération de place incrémentielle, métabalises pour tous les types, refonte luaconf.h, analyseur entièrement réentrant, arguments variadiques. 2006-02-21
5.1.5 2012-02-17
5.2 Ramasse-miettes d'urgence, goto, finaliseurs pour les tables. 2011-12-16
5.2.4 2015-03-07
5.3 Prise en charge de base UTF-8, opérations binaires, nombres entiers de 32/64 bits. 2015-01-12
5.3.4 Dernière version. 2017-01-12

commentaires

Les commentaires d'une seule ligne dans Lua commencent par -- et continuent jusqu'à la fin de la ligne:

-- this is single line comment
-- need another line
-- huh?
 

Les commentaires de bloc commencent par --[[ et se terminent par ]] :

--[[
    This is block comment.
    So, it can go on...
    and on...
    and on....
]]
 

Les commentaires de bloc utilisent le même style de délimiteur que les chaînes longues; n'importe quel nombre de signes égaux peut être ajouté entre les parenthèses pour délimiter un commentaire:

--[=[
    This is also a block comment
    We can include "]]" inside this comment
--]=]

--[==[
    This is also a block comment
    We can include "]=]" inside this comment
--]==]
 

Une astuce pour commenter des morceaux de code est de l'entourer de --[[ et --]] :

--[[
    print'Lua is lovely'
--]]
 

Pour réactiver le bloc, ajoutez simplement a - à la séquence d’ouverture des commentaires:

---[[
    print'Lua is lovely'
--]]
 

De cette façon, la séquence -- dans la première ligne commence un commentaire sur une seule ligne, tout comme la dernière ligne, et l’instruction d’ print n’est pas commentée.

En allant plus loin, deux blocs de code peuvent être configurés de telle manière que si le premier bloc est commenté, le second ne le sera pas et vice-versa:

---[[
  print 'Lua is love'
--[=[]]
  print 'Lua is life'
--]=]
 

Pour activer le deuxième bloc en désactivant le premier bloc, supprimez le premier - sur la première ligne:

--[[
  print 'Lua is love'
--[=[]]
  print 'Lua is life'
--]=]
 

Exécution de programmes Lua

En général, Lua est livré avec deux binaires:

  • lua - interpréteur autonome et shell interactif
  • luac - compilateur bytecode

Disons que nous avons un exemple de programme ( bottles_of_mate.lua ) comme ceci:

local string = require "string"    

function bottle_take(bottles_available)

    local count_str = "%d bottles of mate on the wall."
    local take_str = "Take one down, pass it around, " .. count_str
    local end_str = "Oh noes, " .. count_str
    local buy_str = "Get some from the store, " .. count_str
    local bottles_left = 0

    if bottles_available > 0 then
         print(string.format(count_str, bottles_available))
         bottles_left = bottles_available - 1
         print(string.format(take_str, bottles_left))
    else
        print(string.format(end_str, bottles_available))
        bottles_left = 99
        print(string.format(buy_str, bottles_left))
    end

    return bottles_left
end

local bottle_count = 99

while true do
    bottle_count = bottle_take(bottle_count)
end
 

Le programme lui-même peut être exécuté en exécutant la suite sur Votre shell:

$ lua bottles_of_mate.lua
 

La sortie devrait ressembler à ceci, fonctionnant dans la boucle sans fin:

Get some from the store, 99 bottles of mate on the wall.
99 bottles of mate on the wall.
Take one down, pass it around, 98 bottles of mate on the wall.
98 bottles of mate on the wall.
Take one down, pass it around, 97 bottles of mate on the wall.
97 bottles of mate on the wall.
...
...
3 bottles of mate on the wall.
Take one down, pass it around, 2 bottles of mate on the wall.
2 bottles of mate on the wall.
Take one down, pass it around, 1 bottles of mate on the wall.
1 bottles of mate on the wall.
Take one down, pass it around, 0 bottles of mate on the wall.
Oh noes, 0 bottles of mate on the wall.
Get some from the store, 99 bottles of mate on the wall.
99 bottles of mate on the wall.
Take one down, pass it around, 98 bottles of mate on the wall.
...
 

Vous pouvez compiler le programme dans le bytecode de Lua en exécutant ce qui suit sur votre shell:

$ luac bottles_of_mate.lua -o bottles_of_mate.luac
 

La liste de bytecode est également disponible en exécutant ce qui suit:

$ luac -l bottles_of_mate.lua


main <./bottles.lua:0,0> (13 instructions, 52 bytes at 0x101d530)
0+ params, 4 slots, 0 upvalues, 2 locals, 4 constants, 1 function
    1    [1]    GETGLOBAL    0 -1    ; require
    2    [1]    LOADK        1 -2    ; "string"
    3    [1]    CALL         0 2 2
    4    [22]    CLOSURE      1 0    ; 0x101d710
    5    [22]    MOVE         0 0
    6    [3]    SETGLOBAL    1 -3    ; bottle_take
    7    [24]    LOADK        1 -4    ; 99
    8    [27]    GETGLOBAL    2 -3    ; bottle_take
    9    [27]    MOVE         3 1
    10    [27]    CALL         2 2 2
    11    [27]    MOVE         1 2
    12    [27]    JMP          -5    ; to 8
    13    [28]    RETURN       0 1

function <./bottles.lua:3,22> (46 instructions, 184 bytes at 0x101d710)
1 param, 10 slots, 1 upvalue, 6 locals, 9 constants, 0 functions
    1    [5]    LOADK        1 -1    ; "%d bottles of mate on the wall."
    2    [6]    LOADK        2 -2    ; "Take one down, pass it around, "
    3    [6]    MOVE         3 1
    4    [6]    CONCAT       2 2 3
    5    [7]    LOADK        3 -3    ; "Oh noes, "
    6    [7]    MOVE         4 1
    7    [7]    CONCAT       3 3 4
    8    [8]    LOADK        4 -4    ; "Get some from the store, "
    9    [8]    MOVE         5 1
    10    [8]    CONCAT       4 4 5
    11    [9]    LOADK        5 -5    ; 0
    12    [11]    EQ           1 0 -5    ; - 0
    13    [11]    JMP          16    ; to 30
    14    [12]    GETGLOBAL    6 -6    ; print
    15    [12]    GETUPVAL     7 0    ; string
    16    [12]    GETTABLE     7 7 -7    ; "format"
    17    [12]    MOVE         8 1
    18    [12]    MOVE         9 0
    19    [12]    CALL         7 3 0
    20    [12]    CALL         6 0 1
    21    [13]    SUB          5 0 -8    ; - 1
    22    [14]    GETGLOBAL    6 -6    ; print
    23    [14]    GETUPVAL     7 0    ; string
    24    [14]    GETTABLE     7 7 -7    ; "format"
    25    [14]    MOVE         8 2
    26    [14]    MOVE         9 5
    27    [14]    CALL         7 3 0
    28    [14]    CALL         6 0 1
    29    [14]    JMP          15    ; to 45
    30    [16]    GETGLOBAL    6 -6    ; print
    31    [16]    GETUPVAL     7 0    ; string
    32    [16]    GETTABLE     7 7 -7    ; "format"
    33    [16]    MOVE         8 3
    34    [16]    MOVE         9 0
    35    [16]    CALL         7 3 0
    36    [16]    CALL         6 0 1
    37    [17]    LOADK        5 -9    ; 99
    38    [18]    GETGLOBAL    6 -6    ; print
    39    [18]    GETUPVAL     7 0    ; string
    40    [18]    GETTABLE     7 7 -7    ; "format"
    41    [18]    MOVE         8 4
    42    [18]    MOVE         9 5
    43    [18]    CALL         7 3 0
    44    [18]    CALL         6 0 1
    45    [21]    RETURN       5 2
    46    [22]    RETURN       0 1
 

Commencer

les variables

var = 50 -- a global variable
print(var) --> 50
do
  local var = 100 -- a local variable
  print(var) --> 100
end
print(var) --> 50
-- The global var (50) still exists 
-- The local var (100) has gone out of scope and can't be accessed any longer.
 

les types

num = 20 -- a number
num = 20.001 -- still a number
str = "zaldrizes buzdari iksos daor" -- a string
tab = {1, 2, 3} -- a table (these have their own category)
bool = true -- a boolean value
bool = false -- the only other boolean value
print(type(num)) --> 'number'
print(type(str)) --> 'string'
print(type(bool)) --> 'boolean'
type(type(num)) --> 'string'

-- Functions are a type too, and first-class values in Lua.
print(type(print)) --> prints 'function'
old_print = print
print = function (x) old_print "I'm ignoring the param you passed me!" end
old_print(type(print)) --> Still prints 'function' since it's still a function.
-- But we've (unhelpfully) redefined the behavior of print.
print("Hello, world!") --> prints "I'm ignoring the param you passed me!"
 

Le type spécial nil

Un autre type dans Lua est nil . La seule valeur dans le nil type est nil . nil existe pour être différent de toutes les autres valeurs dans Lua. C'est une sorte de valeur sans valeur.

print(foo) -- This prints nil since there's nothing stored in the variable 'foo'.
foo = 20
print(foo) -- Now this prints 20 since we've assigned 'foo' a value of 20.

-- We can also use `nil` to undefine a variable
foo = nil -- Here we set 'foo' to nil so that it can be garbage-collected.

if nil then print "nil" end --> (prints nothing)
-- Only false and nil are considered false; every other value is true.
if 0 then print "0" end --> 0
if "" then print "Empty string!" --> Empty string!
 

expressions

a = 3
b = a + 20 a = 2 print(b, a) -- hard to read, can also be written as
b = a + 20; a = 2; print(a, b) -- easier to read, ; are optional though
true and true --> returns true
true and 20 --> 20
false and 20 --> false
false or 20 --> 20
true or 20 --> true
tab or {}
  --> returns tab if it is defined
  --> returns {} if tab is undefined
  -- This is useful when we don't know if a variable exists
tab = tab or {} -- tab stays unchanged if it exists; tab becomes {} if it was previously nil.

a, b = 20, 30 -- this also works
a, b = b, a -- switches values
 

Définir des fonctions

function name(parameter)
    return parameter
end
print(name(20)) --> 20
-- see function category for more information
name = function(parameter) return parameter end -- Same as above
 

booléens

Seulement false et nil considérés comme faux, tout le reste, y compris 0 et la chaîne vide, sont évalués comme vrais.

collecte des ordures

tab = {"lots", "of", "data"}
tab = nil; collectgarbage()
-- tab does no longer exist, and doesn't take up memory anymore.
 

les tables

tab1 = {"a", "b", "c"}
tab2 = tab1
tab2[1] = "d"
print(tab1[1]) --> 'd' -- table values only store references.
--> assigning tables does not copy its content, only the reference.

tab2 = nil; collectgarbage()
print(tab1) --> (prints table address) -- tab1 still exists; it didn't get garbage-collected.

tab1 = nil; collectgarbage()
-- No more references. Now it should actually be gone from memory.
 

Ce sont les bases, mais il y a une section sur les tables avec plus d'informations.

conditions

if (condition) then
    -- do something
elseif (other_condition) then
    -- do something else
else
    -- do something
end
 

pour les boucles

Il existe deux types de for boucle dans Lua: un numérique for la boucle et un générique for la boucle.

  • Un numérique for boucle a la forme suivante:

    for a=1, 10, 2 do -- for a starting at 1, ending at 10, in steps of 2
      print(a) --> 1, 3, 5, 7, 9
    end
     

    La troisième expression en une valeur numérique for boucle est l'étape par laquelle la boucle est incrémenté. Cela rend facile de faire des boucles inverses:

     for a=10, 1, -1 do
       print(a) --> 10, 9, 8, 7, 6, etc.
     end
     

    Si l'expression de l'étape est omise, Lua suppose une étape par défaut de 1.

     for a=1, 10 do
       print(a) --> 1, 2, 3, 4, 5, etc.
     end
     

    Notez également que la variable de boucle est locale à la boucle for . Il n'existera plus après la fin de la boucle.

  • Générique for les boucles fonctionnent à travers toutes les valeurs qu'une fonction retourne iterator:

    for key, value in pairs({"some", "table"}) do
      print(key, value)
      --> 1 some
      --> 2 table
    end
     

    Lua fournit plusieurs construit en itérateurs (par exemple, pairs , ipairs ), et les utilisateurs peuvent définir leurs propres itérateurs personnalisés et à utiliser avec générique for les boucles.

faire des blocs

local a = 10
do
    print(a) --> 10
    local a = 20
    print(a) --> 20
end
print(a) --> 10
 

Bonjour le monde

C'est bonjour le code du monde:

print("Hello World!")
 

Comment ça marche? C'est simple! Lua exécute la fonction print() et utilise "Hello World" chaîne "Hello World" comme argument.

Installation

Binaires

Les binaires Lua sont fournis par la plupart des distributions GNU / Linux en tant que package.

Par exemple, sur Debian, Ubuntu et leurs dérivés, il peut être acquis en exécutant ceci:

sudo apt-get install lua50
 
sudo apt-get install lua51
 
sudo apt-get install lua52
 

Il existe des versions semi-officielles pour Windows, MacOS et d'autres systèmes d'exploitation hébergés sur SourceForge .

Les utilisateurs d'Apple peuvent également installer Lua facilement en utilisant Homebrew :

brew install lua
 

(Actuellement, Homebrew a 5.2.4, pour 5.3, voir Homebrew / versions .)

La source

La source est disponible sur la page officielle . L'acquisition de sources et la création de celles-ci devraient être triviales. Sur les systèmes Linux, les éléments suivants devraient suffire:

$ wget http://lua.org/ftp/lua-5.3.3.tar.gz
$ echo "a0341bc3d1415b814cc738b2ec01ae56045d64ef ./lua-5.3.3.tar.gz" | sha1sum -c -
$ tar -xvf ./lua-5.3.3.tar.gz
$ make -C ./lua-5.3.3/ linux
 

Dans l'exemple ci-dessus, nous téléchargeons essentiellement une tarball source depuis le site officiel, vérifions sa somme de contrôle et extrayons et exécutons make . (Vérifiez la somme de contrôle à la page officielle .)

Remarque: vous devez spécifier la cible de construction souhaitée. Dans l'exemple, nous avons spécifié linux . Les autres cibles de construction disponibles incluent solaris , aix , bsd , freebsd , macosx , mingw , etc. Consultez doc/readme.html , qui est inclus dans la source, pour plus de détails. (Vous pouvez également trouver la dernière version du fichier README en ligne .)

Modules

Les bibliothèques standard sont limitées aux primitives:

  • coroutine - fonctionnalité de gestion de coroutine
  • debug - hooks et outils de débogage
  • io - Primitives IO de base
  • package - fonctionnalité de gestion de module
  • string - Chaîne et fonctionnalité de correspondance de modèle spécifique à Lua
  • table - primitives pour traiter un type Lua essentiel mais complexe - tableaux
  • os - opérations de base du système d'exploitation
  • utf8 - primitives UTF-8 de base (depuis Lua 5.3)

Toutes ces bibliothèques peuvent être désactivées pour une version spécifique ou chargées au moment de l'exécution.

Les bibliothèques et infrastructures tierces de Lua pour la distribution des modules sont rares, mais s’améliorent. Des projets comme LuaRocks , Lua Toolbox et LuaDist améliorent la situation. Beaucoup d'informations et de nombreuses suggestions peuvent être trouvées sur l'ancien Wiki Lua , mais sachez que certaines de ces informations sont assez anciennes et obsolètes.

Des choses délicates

Parfois, Lua ne se comporte pas comme on le penserait après avoir lu la documentation. Certains de ces cas sont:

Nil et Rien ne sont pas pareils (PITFALL COMMUN!)

Comme prévu, table.insert(my_table, 20) ajoute la valeur 20 à la table et table.insert(my_table, 5, 20) ajoute la valeur 20 à la 5ème position. Qu'est-ce que table.insert(my_table, 5, nil) fait cependant? On pourrait s'attendre à ce qu'il traite nil comme aucun argument, et insère la valeur 5 à la fin de la table, mais il ajoute réellement la valeur nil à la 5ème position de la table. Quand est-ce un problème?

(function(tab, value, position)
    table.insert(tab, position or value, position and value)
end)({}, 20)
-- This ends up calling table.insert({}, 20, nil)
-- and this doesn't do what it should (insert 20 at the end)
 

Une chose similaire se produit avec tostring() :

print (tostring(nil)) -- this prints "nil"
table.insert({}, 20) -- this returns nothing
-- (not nil, but actually nothing (yes, I know, in lua those two SHOULD
-- be the same thing, but they aren't))

-- wrong:
print (tostring( table.insert({}, 20) ))
-- throws error because nothing ~= nil

--right:
local _tmp = table.insert({}, 20) -- after this _tmp contains nil
print(tostring(_tmp)) -- prints "nil" because suddenly nothing == nil
 

Cela peut également entraîner des erreurs lors de l'utilisation de code tiers. Si, par exemple, la documentation de certaines fonctions indique "renvoie des beignets si chanceux, nul sinon", l'implémentation peut ressembler à ceci

function func(lucky)
    if lucky then
        return "donuts"
    end
end
 

cette mise en œuvre peut sembler raisonnable au début; il retourne des beignets quand il le faut, et quand vous tapez result = func(false) résultat contiendra la valeur nil .

Cependant, si l'on devait écrire print(tostring(func(false))) lua émettrait une erreur qui ressemble à celle-ci stdin:1: bad argument #1 to 'tostring' (value expected)

Pourquoi donc? tostring obtient clairement un argument, même s'il est nil . Faux. func ne retourne rien du tout, donc tostring(func(false)) est identique à tostring() et PAS identique à tostring(nil) .

Les erreurs indiquant "valeur attendue" indiquent clairement que cela pourrait être la source du problème.

Laissant des lacunes dans les tableaux

C'est un énorme piège si vous êtes nouveau sur lua, et il y a beaucoup d' informations dans la catégorie des tables