Initiation au Lua avec Scribunto/Exercices/Sur les tables et les fonctions
Exercice 4-1
modifierÉcrire une fonction, dans un module, qui fait la somme de ses deux arguments écrits en toutes lettres et qui renvoie cette somme, elle aussi, écrite en toutes lettres. Par exemple si l’on rentre, en arguments, six et neuf, le module doit nous renvoyer quinze. On se limitera à faire la somme de nombres compris entre zéro et dix.
La fonction se nomme addition et se trouve dans le module:Opération :
local p = {}
local transcrit = { ["un"] = 1, ["deux"] = 2, ["trois"] = 3, ["quatre"] = 4, ["cinq"] = 5, ["six"] = 6, ["sept"] = 7, ["huit"] = 8, ["neuf"] = 9, ["dix"] = 10}
local retranscrit = { "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", "dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dixsept", "dixhuit", "dixneuf", "vingt"}
function p.addition(frame)
local somme = transcrit[frame.args[1]] + transcrit[frame.args[2]]
return retranscrit[somme]
end
return p
Si, par exemple, nous écrivons {{#invoke:Opération|addition|sept|dix}}, nous obtenons : dixsept
Exercice 4-2
modifierQue retourne une fonction dans laquelle, on n'a pas utilisé l'instruction return? On répondra à cette question après avoir écrit un programme qui nous permettra de trouver la réponse.
On peut raisonnablement penser qu’il y a deux possibilités. Soit la fonction ne retourne rien, soit la fonction retourne nil. Nous écrirons donc, dans un module:Tests, une fonction p.queretourne qui essayera de capter ce que retourne la fonction et de nous l'afficher :
local p = {}
function f(x) -- f est une fonction dans laquelle, nous n'avons pas utilisé return
x = x+7
end
function p.queretourne()
local reponse = "La fonction f a retourné "
local a = 3
if f(a) == nil then
reponse = reponse.."nil"
end
return reponse
end
return p
Si nous écrivons : {{#invoke:Tests|queretourne}}, nous obtenons : La fonction f a retourné nil
Nous retiendrons qu'une fonction, dans laquelle, nous n'avons pas utilisé l'instruction return retourne nil.
Exercice 4-3
modifierDans un module, nous avons écrit :
local p = {}
-- Ce module permet d'étudier la visibilité d'une variable.
local a = 5
function g(x)
a = a + x
local a = 3
a = a + x
return a
end
function p.f()
local reponse = " "
reponse = reponse.." "..a
reponse = reponse.." "..g(a)
reponse = reponse.." "..a
local a = 1
reponse = reponse.." "..a
reponse = reponse.." "..g(a)
reponse = reponse.." "..a
return reponse
end
return p
Qu'obtient-on en appelant la fonction p.f avec la commande #invoke ?
Le programme se trouve dans le module:Visibilité.
En écrivant {{#invoke:Visibilité|f}}, nous obtenons : 5 8 10 1 4 1
On remarque que la fonction g (avant déclaration de sa variable locale a) modifie la variable locale a déclarée en début de module, mais ne modifie pas la variable locale a déclarée dans la fonction p.f, bien que ce soit cette fonction qui appelle la fonction g.
Exercice 4-4
modifierUne fonction peut-elle recevoir en argument une autre fonction ? Pour répondre à la question, on écrira un module comprenant :
- Une première fonction g incrémentant son argument de 3.
- Une seconde fonction h considérant son argument comme étant une fonction qui sera appliqué à un nombre, le résultat étant retourné.
- Une troisième fonction principale p.f Manipulant les deux fonctions g et h de façon à voir si la fonction h accepte bien la fonction g comme argument.
Si le passage de fonction se fait bien, pensez-vous qu’il s'agit d'un passage par valeur ou d'un passage par référence ?
Le module considéré est le module:Fonctions :
local p = {}
function g(x) -- Ici x est considéré comme étant un nombre.
return x+3
end
function h(x) -- Ici x est considéré comme étant une fonction.
return x(7)
end
function p.f()
return h(g)
end
return p
En écrivant {{#invoke:Fonctions|f}}, nous obtenons : 10
Nous constatons que nous avons bien réussi à faire accepter une fonction comme paramètre d'une autre fonction. La question qui se pose maintenant est celle-ci : Le passage d'une fonction se fait-il par valeur ou par référence? On voit mal quel intérêt on pourrait avoir à recopier la fonction lors du passage, d'autant plus que cela peut prendre du temps et peut nécessiter pas mal de mémoire. Nous en déduirons donc que le passage d'une fonction se fait par référence.
Nous pouvons donc en déduire que les tables et les fonctions sont passées par référence. Les autres types de variable sont passés par valeur.