17.4. plural.py, étape 3

Définir de fonctions séparément pour chaque règle de recherche et de transformation n'est pas vraiment nécessaire. Nous ne les appelons jamais séparément, elles sont définies dans la liste de règles rules et appelées à partir de cette liste. Nous allons simplifier la définition des règles en rendant ces fonctions anonymes.

Exemple 17.8. plural3.py


import re

rules = \
  (
    (
     lambda word: re.search('[sxz]$', word),
     lambda word: re.sub('$', 'es', word)
    ),
    (
     lambda word: re.search('[^aeioudgkprt]h$', word),
     lambda word: re.sub('$', 'es', word)
    ),
    (
     lambda word: re.search('[^aeiou]y$', word),
     lambda word: re.sub('y$', 'ies', word)
    ),
    (
     lambda word: re.search('$', word),
     lambda word: re.sub('$', 's', word)
    )
   )                                           1

def plural(noun):                             
    for matchesRule, applyRule in rules:       2
        if matchesRule(noun):                 
            return applyRule(noun)            
1 C'est le même ensemble de règles qu'à l'étape 2. La seule différence est qu'au lieu de définir des fonctions nommées comme match_sxz et apply_sxz, nous avons «inclus» ces définitions directement dans la liste rules, à l'aide de fonctions lambda.
2 Notez que la fonction plural n'a pas changé. Elle parcourt l'ensemble des fonctions de règles, vérifie la première règle et, si celle-ci retourne vrai, appelle la seconde règle et retourne sa valeur. C'est la même fonction qu'à l'étape précédent, mot pour mot. La seule différence est dans la définition des fonctions de règles, mais la fonction plural ne s'en occupe pas, elle sait qu'on lui fournit une liste de règles et elle les applique aveuglément.

Maintenant, pour ajouter une nouvelle règle, il suffit de définir les fonctions directement dans la liste rules : une règle de recherche et une règle de transformation. Mais définir les fonctions de règles de cette manière met en valeur une duplication inutile. Nous avons quatre paires de fonctions qui suivent toutes le même motif. La fonction de recherche est un simple appel à re.search et la fonction de transformation un simple appel à re.sub. Nous allons extraire ces similarités.