Fonctions
Définition
function nom(param1, param2) ... end
local function nom(param1, param2) ... end
local f = function(param1, param2) ... end
function table.champ(x) ... end -- funcname avec '.'
function table:methode(x) ... end -- funcname avec ':' (ajoute implicitement 'self')
function nom(...) ... end est un sucre syntaxique pour nom = function(...) ... end (et de même
pour table.champ.sous.nom avec des . enchaînés). local function nom(...) ... end déclare la
variable locale nom avant de compiler le corps, ce qui permet la récursivité directe.
Appel
f(1, 2)
f "chaine" -- sucre : équivalent à f("chaine")
f { x = 1 } -- sucre : équivalent à f({ x = 1 })
obj:methode(1, 2) -- sucre : équivalent à obj.methode(obj, 1, 2)
Un appel dont l'unique argument est un littéral chaîne ou un constructeur de table peut omettre les parenthèses.
Méthodes et self
function t:m(a) ... end déclare une fonction dont le premier paramètre implicite s'appelle
self (il n'apparaît pas dans la liste de paramètres écrite, mais existe dans le corps, comme un
paramètre local ordinaire) :
local Compte = {}
function Compte:credit(montant)
self.solde = self.solde + montant
end
obj:m(a) appelle la fonction trouvée à obj.m en lui passant obj comme premier argument
(self). C'est une pure question de syntaxe d'appel : obj:m(a) et obj.m(obj, a) sont
équivalents, que la fonction ait été déclarée avec : ou ..
self en dehors d'une déclaration : — une pseudo-variable dynamique
Contrairement à Lua standard, self n'est pas seulement le nom conventionnel du premier
paramètre d'une fonction déclarée avec :. Toute référence à self qui n'est ni un paramètre
déclaré, ni une variable locale, ni un upvalue capturé résout vers une valeur portée par la pile
d'appel courante plutôt qu'un lookup global ordinaire — même dans une fonction déclarée avec .
ou sans nom de table du tout :
function f(a, b)
print(self, a, b)
end
local t = { f = f }
f(1, 2) --> nil 1 2 (appel simple : pas de self)
t:f(1, 2) --> table: ... table: ... 1 (appel-méthode : self = t, ET a = t aussi,
-- par le sucre normal du ':' — deux mécanismes distincts qui coïncident ici)
Cette valeur de self par frame d'appel se résout dans cet ordre :
- Si la fonction est appelée avec
:(obj:f(...)),selfde cette frame vautobj— quefait ou non été déclarée avec:. - Sinon,
selfest hérité de la fermeture englobante : une fonction imbriquée dans le corps d'une méthode (même définie avecfunction, sans:) voit leselfde la méthode qui l'englobe, capturé au moment de la fermeture — pratique pour une fonction utilitaire locale à une méthode sans avoir à la redéclarer avec:ni à passerselfexplicitement. - Sinon
selfvautnil(aucun appel-méthode dans la chaîne d'appel/fermetures).
local Compte = {}
function Compte:relever()
local function afficher() -- pas déclarée avec ':' ...
print(self.solde) -- ... mais voit quand même le 'self' de relever()
end
afficher()
end
Dès que self est un paramètre déclaré (fonction définie avec :) ou une variable locale du même
nom, c'est cette liaison lexicale ordinaire qui s'applique — le mécanisme dynamique ci-dessus ne
sert que de repli quand aucune n'existe. Voir Différences avec Lua
pour ce que ça change par rapport à Lua standard.
Paramètres et arguments
local function f(a, b) ... end
f(1) -- b vaut nil
f(1, 2, 3) -- le 3ᵉ argument est ignoré
Le nombre d'arguments passés n'a pas à correspondre au nombre de paramètres déclarés : les
paramètres manquants valent nil, les arguments excédentaires sont ignorés (sauf s'ils sont
récupérés via ..., voir plus bas).
Fonctions variadiques
local function f(a, ...)
print(a, ...)
local args = { ... }
local n = select("#", ...) -- select() vient de la bibliothèque standard
end
... en dernière position de la liste de paramètres capture tous les arguments restants. Voir
Variables pour son usage comme expression.
Valeurs de retour multiples
local function minmax(t)
return t[1], t[#t]
end
local lo, hi = minmax({ 3, 1, 4, 1, 5 })
Une fonction peut retourner zéro, une ou plusieurs valeurs (return e1, e2, ...). Voir
Variables pour les règles d'adaptation du nombre de valeurs selon le contexte
(affectation, argument, élément de table...).
Fermetures (upvalues)
Une fonction définie à l'intérieur d'une autre capture les variables locales de la fonction englobante qu'elle référence (« upvalues ») — la fermeture reste valide même après le retour de la fonction englobante, et référence la même variable qu'elle (pas une copie figée) :
local function makeCounter()
local n = 0
return function()
n = n + 1
return n
end
end
local next = makeCounter()
print(next(), next(), next()) --> 1 2 3
Chaque appel de makeCounter() crée une nouvelle variable n et donc une fermeture indépendante.
Fonctions anonymes
table.sort(t, function(a, b) return a > b end)
Une expression function(...) ... end (sans nom) est utilisable partout où une expression est
attendue — argument, valeur de table, etc.