Initiation au Lua avec Scribunto/Exercices/Recherche d'erreurs
Exercice 2-1
modifierOn souhaite écrire un module qui traduit en mot un paramètre entré sous forme de chiffre. Par exemple si l’on rentre 8, on souhaite obtenir huit. Dans le Module:Chiffre, on écrit le programme suivant :
local p = {}
function p.traduit(frame) --Fonction traduisant un chiffre en toutes lettres
local reponse = "Chiffre non reconnu"
local chiffre = frame.args[1] --La variable chiffre recueille le premier argument entré sous forme de nombre
if chiffre == 0 then reponse = "zéro" end
if chiffre == 1 then reponse = "un" end
if chiffre == 2 then reponse = "deux" end
if chiffre == 3 then reponse = "trois" end
if chiffre == 4 then reponse = "quatre" end
if chiffre == 5 then reponse = "cinq" end
if chiffre == 6 then reponse = "six" end
if chiffre == 7 then reponse = "sept" end
if chiffre == 8 then reponse = "huit" end
if chiffre == 9 then reponse = "neuf" end
return reponse
end
return p
En testant le programme, nous voyons que : {{#invoke:Chiffre|traduit|7}} donne : Chiffre non reconnu
Expliquer pourquoi le module ne fonctionne pas
Même si à l'appel du module on rentre 7, ce nombre est interprété comme la chaîne de caractère "7". Par conséquent le programme aurait dù être écrit ainsi :
local p = {}
function p.traduit(frame) --Fonction traduisant un chiffre en toutes lettres
local reponse = "Chiffre non reconnu"
local chiffre = frame.args[1] --La variable chiffre recueille le premier argument entré sous forme de nombre
if chiffre == "0" then reponse = "zéro" end
if chiffre == "1" then reponse = "un" end
if chiffre == "2" then reponse = "deux" end
if chiffre == "3" then reponse = "trois" end
if chiffre == "4" then reponse = "quatre" end
if chiffre == "5" then reponse = "cinq" end
if chiffre == "6" then reponse = "six" end
if chiffre == "7" then reponse = "sept" end
if chiffre == "8" then reponse = "huit" end
if chiffre == "9" then reponse = "neuf" end
return reponse
end
return p
ou alors :
local p = {}
function p.traduit(frame) --Fonction traduisant un chiffre en toutes lettres
local reponse = "Chiffre non reconnu"
local chiffre = tonumber(frame.args[1]) --La variable chiffre recueille le premier argument entré sous forme de nombre
if chiffre == 0 then reponse = "zéro" end
if chiffre == 1 then reponse = "un" end
if chiffre == 2 then reponse = "deux" end
if chiffre == 3 then reponse = "trois" end
if chiffre == 4 then reponse = "quatre" end
if chiffre == 5 then reponse = "cinq" end
if chiffre == 6 then reponse = "six" end
if chiffre == 7 then reponse = "sept" end
if chiffre == 8 then reponse = "huit" end
if chiffre == 9 then reponse = "neuf" end
return reponse
end
return p
Exercice 2-2
modifierOn souhaite écrire un programme qui nous confirme le paramètre entré. Après avoir écrit le programme suivant :
local p = {}
local param = frame.args[1]
function p.confirme(frame)
local reponse
reponse = "Le paramètre, que vous avez rentré, est "..param
return reponse
end
return p
on obtient, à l'exécution du programme, le message : Erreur de script.
Expliquez où se trouve l'erreur !
L'erreur vient du fait que l’on a écrit l'instruction :
local param = frame.args[1]
en dehors de la fonction, on aurait dû écrire :
local p = {}
function p.confirme(frame)
local param = frame.args[1]
local reponse
reponse = "Le paramètre, que vous avez rentré, est "..param
return reponse
end
return p
En effet, frame.args[1] recueille le premier paramètre passé à la fonction p.confirme et doit, par conséquent, être mis à l'intérieur de cette fonction.
Exercice 2-3
modifierDans un Module:Calculs, nous écrivons une fonction somme ayant pour but de faire la somme de ses deux arguments.
Nous écrivons :
local p = {}
function p.somme(frame)
local a = frame.arg[1]
local b = frame.arg[2]
c = a + b
return c
end
return p
Nous essayons ensuite de calculer la somme des deux nombres 7 et 4 en écrivant : {{#invoke:Calculs|somme|7|4}} et nous obtenons : Erreur Lua dans Module:Calculs à la ligne 4 : attempt to index field 'arg' (a nil value).
Expliquer pourquoi cela ne fonctionne pas.
Nous avons fait simplement une faute d'orthographe à frame.arg[1] et frame.arg[2]. Il manque un s. Il faut écrire frame.args[1] et frame.args[2]
La version corrigée du programme est donc :
local p = {}
function p.somme(frame)
local a = frame.args[1]
local b = frame.args[2]
c = a + b
return c
end
return p
Cet exercice était un piège en faisant imaginer d'autres erreurs qui n'en étaient pas vraiment.
Beaucoup ont dû penser que l'erreur venait du fait que la variable c n'a pas été déclarée. Le fait de ne pas avoir écrit local c signifie simplement que la variable c n’est pas limitée à la fonction somme. On dit que cette variable est globale.
D'autres ont peut-être pensé, après avoir fait les exercices précédents, que l’on aurait dû utiliser la fonction tonumber pour affecter a et b vu que ces variables étaient destinées à être ajoutées. Effectivement, au départ, a et b étaient bien des chaînes de caractères, mais ces variables sont devenues automatiquement des nombres à cause de la présence du + dans l’expression c = a + b.
Exercice 2-4
modifierOn souhaite écrire une fonction p.sature qui admet comme paramètre un nombre entier. Cette fonction retourne ce nombre si celui-ci est inférieur à 10 et retourne 10 si le nombre est supérieur à 10.
Le programme est ainsi écrit :
local p = {}
function p.sature(frame)
local a = frame.args[1]
if a < 10 then
local b = a
end
if a > 9 then
local b = 10
end
return b
end
return p
Expliquer pourquoi ce programme ne fonctionne pas.
La variable b est déclarée en local dans les tests if et par conséquent n’est pas disponible en dehors des tests if. Le b de l'instruction return b n'est donc pas le b que l’on avait dans les tests if. return b retourne donc nil.
Une façon correcte d'écrire le programme aurait été :
local p = {}
function p.sature(frame)
local a = frame.args[1]
if a > 10 then
a = 10
end
return a
end
return p