Réfléchissez à vos noms de variables !

Billet d'humeur

Bien nommer ses variables est une pratique enseignée très tôt aux programmeurs débutants. Pourtant, il y a parfois des surprises, comme le montrent les exemples ci-dessous, malheureusement inspirés de faits réels.

Il y a évidemment des cancres qui vont nommer leur variables avec des noms incongrus, en particulier s’ils pensent que leurs scripts sont jetables.

# Conversion de degrés vers des tours (un tour = 360 °)
angle_degrees = some_function()
sdfsdf = 1/360 # Quelle horreur !
angle_turns = sdfsdf * angle_degrees

D’autres sont plus appliqués, mais manquent un peu de pratique pour choisir un nom vraiment utile.

# Conversion de degrés vers des tours (un tour = 360 °)
angle_degrees = some_function()
inv_360 = 1/360 # Drôle de paraphrase... Heureusement que le calcul n'est pas plus long !
angle_turns = inv_360 * angle_degrees

On peut faire mieux en indiquant la fonction de cette variable dans son nom plutôt que simplement sa valeur, ce qui est malheureusement pas toujours le cas.

# Conversion de degrés vers des tours (un tour = 360 °)
angle_degrees = some_function()
degrees2turns = 1/360 # Mieux !
angle_turns = degrees2turns * angle_degrees


Il n’y aura probablement jamais de nom de variable parfait, mais réfléchir un peu plus permet souvent d’éviter des noms maladroits voire totalement foireux.

24 commentaires

Bien nommer ses variables est une pratique enseignée très tôt au programmeurs débutants.

Sur des tutoriels comme on a connus sur feu site du zéro, oui. A l’école, pas toujours.

Il est aussi important de choisir des noms concis. Un peu comme les commandes unix (pwd au lieu de givemethefullpathwhereiam).

+7 -0

D’ailleurs j’ai toujours trouvé que les noms de variables qui ne sont qu’un changement d’unité en a2b prêtent à confusion. Je préfère un a_per_b ou b_per_a qui montrent tout de suite ce qui se passe. Pour moi a2b fait plutôt penser à un flux ou à une fonction qui ferait la conversion entre deux unités.

Typiquement, la troisième ligne serait plus claire ainsi

1
turns = turn_per_deg * angle_degrees

La symétrie des unités des objets autour du coefficient turn_per_deg est assez satisfaisante.

Je rajoute ces points que j’ai beaucoup trop vus :

  1. Attention à l’orthographe !
  2. Si le langage a une convention, la respecter. Surtout si elle permet de différencier les types d’identificateurs (constante, variable, fonction, classe…)1
  3. Si la variable/classe/méthode/constante… change de sens à l’évolution du code, il faut la renommer. C’est très désagréable de se rendre compte que la fonction faitUnTruc() ne fait plus le truc.

  1. Par exemple, en Java on peut perdre beaucoup de temps à comprendre que le programme ne fonctionne pas car EXEMPLE_DE_VALEUR est une variable modifiée dans le programme, et non une constante comme le laisse penser sa casse… L’IDE aide un peu, mais la différence entre « erreur de casse » et « oubli du final à la déclaration » n’est pas évident. 

Il est aussi important de choisir des noms concis. Un peu comme les commandes unix (pwd au lieu de givemethefullpathwhereiam).

Ge0

Une bonne "règle" est que la longueur du nom d’une variable est proportionnelle à la taille de son scope.

Pour reprendre ton exemple de pwd, le résultat de pwd est cwd (print working directory affiche le current working directory). Imagine t’as un programme, et dans un scope un peu gros t’as une variable cwd. Y’a bien des chances que tu saches plus exactement à quoi elle fait référence, et t’aurais mieux fait de la nommer project_root_path, log_tmp_dir ou un truc du genre.

En revanche si tu fais for (let i = 0; i < 10; i++) le scope est généralement minuscule, tu peux bien te permettre d’avoir des variables nommées comme ça.

Ou si tu fais def swap(a, b): a, b = b, a, là aussi on s’en tape, scope ridicule.

(Attention hein quand je dis "règle", c’est pas un truc à appliquer à la lettre, n’allez pas compter les scopes, n’allez pas nommer toutes les variables d’un même scope avec exactement le même nombre de caractères, etc. Be smart! comme dirait l’autre relou.)

+14 -0

Tu pourrais développer ?

SpaceFox

L’idée est que même si le nom n’est absolument pas parlant, le système de type va

  • Te permettre de savoir ce que tu peux faire ou non avec (aspect informatif du typage). Ca peut meme aider à inférer l’origine du nom de la variable, surtout si on couple avec des aspects métier du code.
  • Empêcher certaines opérations qui n’ont pas de sens (aspect correction/prévention du typage).

Dans l’exemple considéré, ca se voit. L’information du typage est dans le nom des variables (angle_degrees, degrees2turns). Elle devrait être dans le système de type.

+0 -0

Cela dit, les gens avec suffisament de bouteille et de recul pour être capables d’utiliser correctement un bon sytème de type pouvant gérer ça sont aussi capables de nommer correctement leurs variables…

Le système de type déplace intelligemment les difficultés dans la conception d’un bon code, mais ne les enlève pas totalement.

Cela dit, les gens avec suffisament de bouteille et de recul pour être capables d’utiliser correctement un bon sytème de type pouvant gérer ça sont aussi capables de nommer correctement leurs variables…

J’ai eu un directeur technique qui nommait ses variables a ou zz et pourtant du métier il en avait (et n’était pas mauvais non plus, juste que ses codes étaient une plaie à reprendre)

+1 -0

Dans "être capable d’utiliser correctement un bon système de type", il y a aussi "être capable de nommer correctement les types en question" (j’imagine que c’était pas mieux que les variables…). On peut être très bon sur le plan purement technique, si on écrit du code illisible, on n’est pas un bon développeur… Ça fait partie intégrante du truc, mon point était que le système de type, aussi bon soit il, ne fait que déplacer le problème du nommage (en réduisant les conséquences d’un nommage mauvais, peut être…). Un dev pas capable de nommer ses variables fera pas mieux avec ses types.

Dans l’exemple considéré, ca se voit. L’information du typage est dans le nom des variables (angle_degrees, degrees2turns). Elle devrait être dans le système de type.

Davidbrcz

Pourtant ces 2 variables correspondent juste à des valeurs numériques. Tu veux dire qu’il faudrait avoir des types plus précis prenant en compte les unités de ces valeurs ?

Pour un code qui gère beaucoup d’angles, il serait pas délirant d’avoir trois types d’angles pour indiquer si la valeur est en radians, en degrés ou en tours. Ça éviterait l’erreur classique de filer des degrés à une fonction définie pour des radians puisque le code ne compilerait même pas.

Le système de type déplace intelligemment les difficultés dans la conception d’un bon code, mais ne les enlève pas totalement.

C’est ce que je dis, ca limite les conséquences.

Après tu en parles comme si c’était optionnel ou la charge du développeur. Mais si tu utilises une bibliothèque avec interface bien foutue dans un langage assez strict, tu n’as pas trop le choix sur la manière dont doit être typé le programme, que tu sois débutant ou non.

Pourtant ces 2 variables correspondent juste à des valeurs numériques. Tu veux dire qu’il faudrait avoir des types plus précis prenant en compte les unités de ces valeurs ?

Oui. Et de manière générale, tous les calculs liés à la physique devraient prendre en compte les unités pour éviter des erreurs. Ca marche aussi être d’autres choses. Par exemple le PWM pour commander des servomoteurs, est ce que la commande est entre 0-100 (en pourcentage) ou entre 0 et une valeur max. Si ton interface est juste un int, c’est compliqué, avec un système de type plus évolué, moins de risque d’erreur

Ce que tu dis Davidbrcz est intéressant, mais d’expérience éloigné de la réalité du terrain. Parce que même avec un système de types fort et statique :

  • Ça implique que le typage et les API soient bien faites, ce qui n’est pas toujours le cas, loin de là.
  • Ça ne résoud en rien le problème des noms de variables pourris : les idioties du même niveau que Chocolat carotte = new Chocolat();, j’en ai vu passer des zillions.

Tes exemples sont pertinents parce qu’ils sont liés à un système physique sous-jacent (des calculs physiques, une interface de commande de moteur). Mais l’immense majorité du code, c’est de la manipulation de données abstraites.

Tes exemples sont pertinents parce qu’ils sont liés à un système physique sous-jacent (des calculs physiques, une interface de commande de moteur). Mais l’immense majorité du code, c’est de la manipulation de données abstraites.

SpaceFox

J’ai l’impression que ça dépend aussi du langage dans lequel tu programmes.

Dans un langage bas niveau comme le C où tu fais attention à la mémoire, d’un côté la guideline du noyau Linux te demande d’avoir un nommage spartiate de tes variables1, d’un autre la programmation autour des API Win32 te recommande la notation hongroise où il t’est aisé de deviner le type d’une variable par son nom. Tu as quelques exemples sur mon billet récent : Ne loupez pas le coche ! où tu vois que des "handles" sont préfixés de la lettre h, où des pointeurs sont préfixés des lettres lp (comprendre "long pointer" qui provient d’une époque où on faisait la différence entre les pointeurs 16 bits et les pointeurs 32 bits…), etc.

Pour les langages de haut niveau, évidemment ce genre de question ne se pose plus car, pour reprendre tes dires, "c’est de la manipulation de données abstraites". En connaissance de cause je ne sais absolument pas ce qui se cache derrière un String en Java ou derrière un list en python et, en programmeur honnête que je suis, je m’en fous. :) 2


  1. "C is a Spartan language, and so should your naming be." - Linux Kernel coding style 

  2. Ce qui ne m’empêcherait pas d’être curieux à titre purement personnel, bien sûr ! 

Oui. Et de manière générale, tous les calculs liés à la physique devraient prendre en compte les unités pour éviter des erreurs.

Un code de physique écrit intelligemment manipule des variables adimensionnées de toute façon (pour des raisons de taille de l’espace des paramètres et de conditionnement des opérateurs), donc ça devient difficile de garder des unités…

Je ne suis pas trop d’accord sur ce qui a été dit sur l’enseignement. J’ai toujours vu des professeurs parler de bien structurer le code. Par contre, il est rare de voir un étudiant le faire. Par non intérêt, paresse ou autre. Dans la même optique, je suis sûr qu’il est possible d’avoir de nombreux témoignages de personnes souhaitant montrer Git aux autres membres de leur groupe et qui n’ont pas réussi à les convaincre. Au final, on finit avec : v1, v2, vX, version_final, version_final2, der_des_ders, etc.

J’essaye de nommer mes variables du mieux que je peux. Il y a quelque chose dont je pense à mettre en place de plus en plus : ne pas écrire les noms des variables dans l’ordre du langage. Par exemple, au lieu d’utiliser contenuCommentaire, je pense à opter pour commentaire_contenu. J’utilise le camelCase pour le tout ce qui se trouve après le préfixe, qui se différencie du reste par u tiret bas.

J’ai pour habitude de classer mes variables par ordre alphabétique quand je les déclare. Pensez-vous que cette méthode hybride est bien ?

J’ai pour habitude de classer mes variables par ordre alphabétique quand je les déclare. Pensez-vous que cette méthode hybride est bien ?

Helmasaur

Mon avis c’est que si on en est au point de devoir faire une dichotomie mentale pour retrouver la bonne déclaration, faut ptete d’abord se poser des questions de modularité… Au risque d’être tautologique, je pense que c’est tout simplement mieux de mettre ensemble ce qui va ensemble.

(Par rapport au sujet, il y a un moment où je m’étais fixé des conventions de nommage ultra strictes, mais finalement ça s’est avéré plus contre-productif qu’autre chose. Aujourd’hui j’en garde quelques séquelles — toute une gamme de nommage cohérente, du genre nb_, _of_, les fonctions en verbe + complément —, mais je pense qu’avec un minimum d’expérience, choisir un identificateur au feeling c’est finalement le meilleur choix.)

je pense qu’avec un minimum d’expérience, choisir un identificateur au feeling c’est finalement le meilleur choix.)

Lucas-84

Je pense aussi, à condition de garder une cohérence interne avec quelque chose de systématique. La cohérence interne permet de comprendre facilement, et le fait que ce soit systématique permet de deviner certains noms, ce qui peut être pratique.

Par exemple, pour élaborer sur l’exemple du billet, tu pourrais avoir des positions angulaires et vitesses angulaires de différents axes. Dans ce cas, on pourrait adopter une convention du type <Composant><Grandeur>, ce qui donnerait MotorPosition, MotorSpeed, WheelPosition, WheelSpeed. On peut même élaborer encore plus avec des qualificateurs, et avoir des variables du type MotorSpeedMeasured, MotorSpeedRequested, etc.

Si tu utilises purement le feeling, d’un endroit à l’autre, tu auras des SpeedMotor et MeasuredMotorSpeed et plus personne n’y comprendra rien. Après évidemment, si c’est juste pour nommer une variable dans une sous-fonction, c’est un peu hors de propos d’avoir tout un système de nommage.

Petite question d’une personne faisant ses premiers pas : est-il recommandé de nommer ses variables en Anglais? Parce que c’est beaucoup plus facile pour moi de comprendre qui sert à quoi en Français :o

ToxicScorpius

Je pense qu’il y a eu de longs débats sur cette question.

Personnellement, je vois ces arguments-là qui poussent à utiliser l’anglais :

  • on souhaite garder la cohérence interne avec le langage, qui a en général des mots-clés en anglais ;
  • la langue de travail de l’organisation est l’anglais, que ce soit une entreprise, fondation, etc. ;
  • on veut rester ouvert à des contributeurs externes, par exemple sur un projet libre.

Si les arguments ci-dessus ne s’appliquent pas, il y a plein de raisons de ne pas utiliser l’anglais :

  • tu perds en efficacité en le faisant ;
  • tu parles suffisamment mal anglais pour que cela créée plus de confusion qu’autre chose pour les relecteurs ;
  • tes relecteurs sont majoritairement francophones …

J’aime beaucoup la langue française donc quand je peux éviter des anglicismes, je le fais. Par contre, quand je crée un programme, je mets les noms en anglais. Aabu l’a indiqué dans son énumération :

  • on souhaite garder la cohérence interne avec le langage, qui a en général des mots-clés en anglais
Aabu

Par contre, si je travaille avec d’autres personnes et que l’anglais est un frein, je vais le faire en français sauf pour des cas particuliers comme pour les setters et les getters. Dans ce cas, je trouve qu’il s’agit d’une convention proche des mots-clés d’un langage (comme new par exemple).

Il y a un derniers cas que j’aimerait traité : les cours dans une école. Si le professeur a du mal avec l’anglais, je conseillerai de nommer les variables en français pour faciliter la compréhension de ce que tu fais.

L’anglais n’est plus aussi essentiel qu’auparavant dans l’informatique. Il y a beaucoup plus de documentations dans d’autres langues. Si tu n’y arrives vraiment pas, je ne pense pas que ça soit une bonne idée de nommer tes variables en anglais, surtout si tu y fais des fautes à chaque fois.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte