Introduction au Lua/Erreurs

Leçons de niveau 12
Une page de Wikiversité, la communauté pédagogique libre.
Début de la boite de navigation du chapitre
Erreurs
Icône de la faculté
Chapitre no 11
Leçon : Introduction au Lua
Chap. préc. :Tables
Chap. suiv. :Fonctions Math
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Introduction au Lua : Erreurs
Introduction au Lua/Erreurs
 », n'a pu être restituée correctement ci-dessus.


Après avoir abordé la structure particulière des modules Scribunto pour Mediawiki, nous avons ensuite étudié quelques caractéristiques élémentaires du langage Lua (ses variables, ses expressions) d'autres caractéristiques fondamentales comme les conditions, les boucles ou encore les fonctions. Nous avons vu ensuite comment la manipulation des tables avec Lua est à la fois essentielle et particulière. Cette nouvelle leçon montre comment gérer les erreurs et exceptions au sein d'un script en cours d’exécution[1].

Prérequis[modifier | modifier le wikicode]

Cette leçon suppose que vous ayez assimilé la leçon Tables.

Créer un script Lua avec un système de gestion des exceptions[modifier | modifier le wikicode]

  1. Accéder au Module:Sandbox.
  2. Supprimer le code existant.
  3. Ajouter le code suivant et enregistrer la page:
local p = {}
 
local function reciprocal1(value)
    return 1 / value
end
 
function p.test1(frame)
    local value = frame.args[1]
    return reciprocal1(value)
end
 
local function reciprocal2(value)
    if value == nil then
        error('value must exist')
    end
    if tonumber(value) == nil then
        error('value must be a number')
    end
    if tonumber(value) == 0 then
        error('value must not be 0')
    end
    return 1 / value
end
 
function p.test2(frame)
    local value = frame.args[1]
    return reciprocal2(value)
end
 
local function reciprocal3(value)
    assert(value, 'value must exist')
    assert(tonumber(value), 'value must be a number')
    assert(tonumber(value) ~= 0, 'value must not be zero')
    return 1 / value
end
 
function p.test3(frame)
    local value = frame.args[1]
    return reciprocal3(value)
end
 
function p.test4(frame)
    local value = frame.args[1]
    if pcall(function () result = reciprocal3(value) end) then 
        return result
    else
        return 'Error: Value must exist, must be numeric, and not zero.'
    end
end
 
return p

Tester votre nouveau script[modifier | modifier le wikicode]

  1. Rendez-vous sur "votre page de test".
  2. Ajouter le code suivant et enregistrer la page:
;Reciprocal 1
:{{#invoke:Sandbox|test1}}
:{{#invoke:Sandbox|test1|x}}
:{{#invoke:Sandbox|test1|0}}
:{{#invoke:Sandbox|test1|2}}
;Reciprocal 2
:{{#invoke:Sandbox|test2}}
:{{#invoke:Sandbox|test2|x}}
:{{#invoke:Sandbox|test2|0}}
:{{#invoke:Sandbox|test2|2}}
;Reciprocal 3
:{{#invoke:Sandbox|test3}}
:{{#invoke:Sandbox|test3|x}}
:{{#invoke:Sandbox|test3|0}}
:{{#invoke:Sandbox|test3|2}}
;Reciprocal 4
:{{#invoke:Sandbox|test4}}
:{{#invoke:Sandbox|test4|x}}
:{{#invoke:Sandbox|test4|0}}
:{{#invoke:Sandbox|test4|2}}

Le résultat doit correspondre à ceci:

;Reciprocal 1
    'Erreur Lua dans Module:Sandbox à la ligne 4 : attempt to perform arithmetic on local 'value' (a nil value).'
    'Erreur Lua dans Module:Sandbox à la ligne 4 : attempt to perform arithmetic on local 'value' (a string value).'
    inf
    0.5
;Reciprocal 2
    'Erreur Lua dans Module:Sandbox à la ligne 14 : value must exist.'
    'Erreur Lua dans Module:Sandbox à la ligne 17 : value must be a number.'
    'Erreur Lua dans Module:Sandbox à la ligne 20 : value must not be 0.'
     0.5
;Reciprocal 3
    'Erreur Lua dans Module:Sandbox à la ligne 31 : value must exist.'
    'Erreur Lua dans Module:Sandbox à la ligne 32 : value must be a number.'
    'Erreur Lua dans Module:Sandbox à la ligne 33 : value must not be zero.'
    0.5
;Reciprocal 4
    'Error: Value must exist, must be numeric, and not zero.'
    'Error: Value must exist, must be numeric, and not zero.'
    'Error: Value must exist, must be numeric, and not zero.'
    0.5

Comprendre le nouveau script[modifier | modifier le wikicode]

Comprendre la fonction reciprocal1[modifier | modifier le wikicode]

  1. local function reciprocal1(value) déclare une fonction locale nommée reciprocal1 qui accepte un unique paramètre value, qui est la valeur dont l'inverse sera retourné.
  2. return 1 / value retourne l'inverse de la valeur.
  3. end termine la fonction.

Comprendre la fonction test1[modifier | modifier le wikicode]

  1. function p.test1(frame) déclare une fonction locale nommée test1 qui accepte un unique paramètre frame, qui est l'objet utile pour accéder aux paramètres passés par #invoke.
  2. local value = frame.args[1] définit une variable locale nommée value et lui assigne la valeur du premier argument (paramètre) de l’objet "frame" passé par #invoke.
  3. return reciprocal1(value) appel la fonction reciprocal1, en lui passant la variable value et retourne le résultat.
  4. end termine la fonction.

Comprendre la fonction reciprocal2[modifier | modifier le wikicode]

  1. local function reciprocal2(value) déclare une fonction locale nommée reciprocal2 qui accepte un unique paramètre value, qui est la valeur dont l'inverse sera retourné.
  2. if value == nil then créé un bloc conditionnel et test si la variable value est de type nil. Dans l'affirmative une erreur est générée.
  3. error('value must exist') génère une erreur avec la chaîne de caractère littérale comme message d'erreur (error statement). L'utilisation de la fonction error() permet au programmeur de choisir le texte du message d'erreur qui sera retourné à la fonction ou à la page qui a invoqué la fonction.
    Lorsqu'une erreur est générée, l’exécution retourne immédiatement à la fonction appelante. Aucune instruction dans cette même fonction venant après l'erreur ne sera traitée.
  4. ...if tonumber(value) == nil créé un bloc conditionnel et test si la variable value est de type numérique. Dans la négative le code, tonumber retourne nil et une erreur est générée. (convertit en numerique et évalue si le résultat vaut zéro)...
  5. if tonumber(value) == 0 créé un bloc conditionnel et test si la variable value vaut 0. Dans l'affirmative une erreur est générée.
  6. return 1 / value retourne l'inverse de la valeur.
  7. end termine la fonction.

Comprendre la fonction test2[modifier | modifier le wikicode]

  1. function p.test2(frame) et le code qui suit, déclare une fonction locale nommée test2 qui accepte un unique paramètre frame, qui est l'objet utile pour accéder aux paramètres passés par #invoke.
  2. local value = frame.args[1] définit une variable locale nommée value et lui assigne la valeur du premier argument (paramètre) de l’objet "frame" passé par #invoke.
  3. return reciprocal2(value) appel la fonction reciprocal2, en lui passant la variable value et retourne le résultat.
  4. end termine la fonction.

Comprendre la fonction reciprocal3[modifier | modifier le wikicode]

  1. local function reciprocal3(value) déclare une fonction locale nommée reciprocal3 qui accepte un unique paramètre value, qui est la valeur dont l'inverse sera retourné.
  2. ...assert(value, 'value must exist') créé une condition interne qui test si la variable value est de type nil Dans l'affirmative une erreur est générée...
    L'usage de assert fait partie des meilleures pratiques pour documenter et tester les postulats sur les variables passées en paramètres.
  3. assert(tonumber(value), 'value must be a number') créé une condition interne qui test si la variable value est de type numérique. Dans la négative, tonumber retourne nil, une erreur est générée.
  4. assert(tonumber(value) ~= 0, 'value must not be zero') créé une condition interne qui test si la variable value vaut 0. Dans l'affirmative une erreur est générée.
  5. return 1 / value retourne l'inverse de la valeur.
  6. end termine la fonction.

Comprendre la fonction test3[modifier | modifier le wikicode]

  1. function p.test3(frame) et le code qui suit, déclare une fonction locale nommée test3 qui accepte un unique paramètre frame, qui est l'objet utile pour accéder aux paramètres passés par #invoke.
  2. local value = frame.args[1] définit une variable locale nommée value et lui assigne la valeur du premier argument (paramètre) de l’objet "frame" passé par #invoke.
  3. return reciprocal3(value) appel la fonction reciprocal3, en lui passant la variable value et retourne le résultat.
  4. end termine la fonction.

Comprendre la fonction test4[modifier | modifier le wikicode]

  1. function p.test4(frame) et le code qui suit, déclare une fonction locale nommée test4 qui accepte un unique paramètre frame, qui est l'objet utile pour accéder aux paramètres passés par #invoke.
  2. local value = frame.args[1] définit une variable locale nommée value et lui assigne la valeur du premier argument (paramètre) de l’objet "frame" passé par #invoke.
  3. if pcall(function () result = reciprocal3(value) end) then créé une condition interne qui appel la fonction reciprocal3, lui passe la variable value et stocke le résultat. Si aucune erreur ne se produit, la variable result est retournée. Si une erreur se produit, une chaine de caractère est renvoyé comme message d'erreur.
  4. pcall() utilise la fonction prédéfinie pcall (protected call) pour appeler une seconde fonction et intercepter les erreurs qui ont lieu.
  5. function () ... end créé une fonction interne anonyme qui exécute le code dans ... comme un appel de fonction.
    La fonction anonyme est nécessaire pour enregistrer le resultat de la fonction reciprocal3 alors que la fonction pcall() sert à intercepter n'importe quelle erreur qui se produit.
  6. end termine la fonction.

Conclusion[modifier | modifier le wikicode]

Félicitation! Vous êtes capable de créer, tester et comprendre un script Lua qui contient un système de gestion des erreurs et exceptions. Continuez avec la leçon suivante Fonctions mathématiques ou choisissez l'étude d'une autre bibliothèque Lua ou Scribunto dans la barre verticale.

Voir aussi[modifier | modifier le wikicode]

Références[modifier | modifier le wikicode]

Lua for Wikiversity (en)