Vos petites manies de développeurs

Les petites choses dont vous ne vous pouvez vous passez lorsque vous vous trouvez dans un éditeur de texte, un gestionnaire de versions...

a marqué ce sujet comme résolu.

Si, ça a été dit, et c'est pour ça que je reprends le propos.

La plupart du code écrit est plus ou moins autodocumenté pour permettre, comme Stranger l'a également dit, de comprendre les fonctionnalités uniquement avec les prototypes et l'autocomplétion.

Fraggy

entwanne

My bad je me suis mal exprimé. Il fallait lire "trouver" et non "comprendre". Le principe étant qu'avec du code autodocumenté, tu es capable de comprendre l'effet d'une fonction/d'un attribut juste en lisant son nom. Du coup, quand tu recherche une fonction précise dans une classe que tu connais pas, tu la trouve en 2 sec.

+0 -0

@nohar : pour faire du python et avoir essayé de suivre la PEP-8 à la lettre, j'ai une grande question qui m'est venue : comment, grand Dieu comment fait-on tenir du code python sur 80 caractères ? comment ? J'ai des lignes de 100 caractères, mais je peux juste pas décemment les diminuer proprement pour la simple et bonne raison que j'aime avoir des noms de variables explicites, et donc potentiellement longs (après tout, tout le monde a l'autocomplete aujourd'hui, je refuse de faire plaisir à ceux qui ne l'ont pas) et dans ces cas-ci, le moindre appel de fonction ne tient simplement pas sur une ligne… Comment faire dans ce cas ? Des splits dégueulasses au milieu des parenthèses ? Et après tout, pourquoi se limiter à 80 caractères alors que n'importe quel éditeur (éditeurs en console compris) offre une fonctionnalité de soft wrap ? Pourquoi se casser la tête à salir volontairement son code alors que les éditeurs d'aujourd'hui peuvent l'adapter à notre écran/nos splits ?

En suivant vraiment la PEP-08, donc en apprenant à découper les appels de fonctions un peu compliqués sur plusieurs lignes sans nuire à la lisibilité du code. Le Python-mode de Vim le fait très bien avec gg=G d'ailleurs.

80 caractères c'est la mort quand même

Thiht

Bof, question d'habitude. Respecter cette limite ne me dérange absolument pas.

À propos des noms de variable, explicite n'a pas être synonyme de "long". Ça demande aussi pas mal de pratique pour trouver immédiatement un nom de variable qui soit à la fois explicite et court, mais y'a pas mal de techniques pour ça. En particulier, ne mettre que les principales consonnes du mot (hdlr au lieu de handler) permet d'identifier tout de suite le mot, sans nuire à sa lisibilité, tout en le raccourcissant de moitié. D'ailleurs, même si je dépasse rarement les 5 ou 6 caractères par variable en longueur, je n'en utilise que très exceptionnellement moins de 3.

+0 -0

Et moi je vous garantis que dans le contexte hdlr = get_handler(data) vous comprenez tout de suite de quoi il s'agit. Sachant que les fonctions sont courtes et simples (pas plus de 3 niveaux d'indentation), le contexte reste frais en mémoire et il n'y a pas besoin de chercher 6 plombes d'où viennent les variables.

+0 -0

À la définition d'accord, mais ailleurs dans le code ?

SpaceFox

C'est ce que je disais en parlant de contexte court : les fonctions qui font plus d'une page (50 lignes) sont vraiment, vraiment rares quand on se limite à 3 niveaux d'indentation par fonction.

En fait pour que ce soit bien clair il ne faut pas se contenter de parler dans le vent mais raisonner sur des exemples de code. Je ne peux pas en sortir de la codebase de mon boulot et je n'ai pas le temps d'en chercher un là tout de suite.

+1 -0

Idem je pense que les guide line de style ne sont valables que prise dans leur ensemble. Par exemple oui il m'arrive de faire des variables avec un nom de un seul caractère : quand ce sont les variables de boucles de lists en compréhension. La définition, leur provenance et leur utilisation sont sur la même ligne, ça ne pose aucun problème. D'ailleurs pylint ne gueule pas sur ces noms alors qu'il le fait quand c'est une variable locale classique, je dois pas être le seul à considérer que c'est un cas particulier justifié.

Comme dit nohar je pense qu'il faut le contexte pour juger. Dans la codebase d'Helium Rain, il y a dans à peu près tous les fichiers une occurrence d'une variable PC pour PlayerController. A première vue c'est pas clair comme nom de variable, mais elle est tellement omniprésente que quand on l'a vue une fois on ne se pose plus la question, et utiliser un autre nom ailleurs porterait presque à confusion…

Stranger

En fait, je pense qu'on trouve ce genre de variables dans à peu près toutes les codebases. Je suppose que les noms src et dst ne diront rien (surtout pris séparément) à quiconque n'a jamais eu à utiliser OpenCV. Sauf que du jour où l'on utilise UNE de ses milliers de fonctions, on sait définitivement que src désigne la source et dst la destination d'un traitement et ce dans TOUTE son API.

De la même manière, j'affirme qu'il existe des tonnes de cas génériques de ce genre, qu'il suffit de voir une seule fois et d'adopter pour que ça devienne des idiomatismes. Les plus connus sont tmp pour un résultat temporaire, buf pour un buffer, res pour stocker un résultat que l'on construit au fur et à mesure, ou encore path, dir… Et tous ces trucs génériques peuvent se décliner en étant préfixés ou suffixés d'annotations du style in ou out (pour faire référence à l'entrée ou la sortie…). Mais peut-être que c'est moi qui invente le rapport pas du tout évident entre in et une entrée ou entre dir et un répertoire ?

Il ne s'agit pas seulement d'écriture (moi aussi j'utilise l'autocomplétion, le problème n'est pas là), mais également de simplifier la lecture grâce à des idiomatismes.

+1 -0

res pour stocker un résultat que l'on construit au fur et à mesure,

Bah, ça se discute :|

Pour moi res c'est quasi systématiquement le résultat d'un traitement sur lequel je n'ai pas la main, et qui est terminé.

1
2
3
4
5
myApi.doSomething(res -> {
   if (res.success) {
   } else {
   }
});

Pour un résultat pas encore terminé, en cours, qui va finir, que je suis en train de construire, … j'utilise future ou si on prend ta version, fut du coup.

1
2
3
4
private void someLongAsyncStuff(Future fut) {
// blah
fut.complete();
}

Bon c'est qu'un simple exemple qui m'a frappé en lisant ton texte, mais c'est pour ça que je suis assez réservé avec les "idiomatismes" ou autres "conventions". Pour être rentré plusieurs fois dans des équipes en place, y'a déjà énormément d'abus de langage (un classe "MachineChouetteManager" qui est un singleton, etc.) auxquels il faut faire face, voire du jargon "made in l'équipe" que tu comprends absolument pas, je suis pas trop fan de "c'est des idiomatismes, c'est sous-entendu, c'est plus simple".

Pour aller à l'extrême, j'ai vu (de mes yeux, je le jure), un mec qui manipulait des variables JS (globales hein ! sinon c'est pas drôle) d'une lettre :

1
2
3
if (window.c) {
  ///
}

"Bah 'c' c'est controller… Evidemment" m'a-t-il dit en me regardant béat.

+2 -0

Chez moi une variable res c'est généralement une liste qui se remplit au fur et à mesure de la fonction avant de terminer par un return res une dizaine de lignes plus bas. J'ai beaucoup de mal à croire que ce soit une pratique arcane.

De la même manière, je trouverais idiot dans un jeu de se priver d'itérer sur x et y ou de ne pas noter dx ou dy un déplacement, alors que ce sont des notations universelles pour se situer dans un plan ou pour décrire une différence atomique.

Note enfin que je ne parle ici que de variables locales et non d'attributs. :)

PS : Il y a aussi le contexte de l'application (son "domaine" métier) qui entre en jeu. Je trouverais mignon un code orienté système qui contiendrait une variable file_descriptor alors que les stubs des appels système dans les pages man de Linux prennent un fd en premier paramètre, par exemple.

+2 -0

Chez moi une variable res c'est généralement une liste qui se remplit au fur et à mesure de la fonction avant de terminer par un return res une dizaine de lignes plus bas. J'ai beaucoup de mal à croire que ce soit une pratique arcane.

nohar

J'ai absolument pas dit ça, que c'était marginal ou quoi, j'ai dit que ça rentre en collision avec d'autres pratiques. Typiquement dans l'asynchrone, res c'est souvent le résultat d'un traitement asynchrone. (et je l'invente pas hein, les deux exemples ci-dessus que j'ai donnés de tête se retrouvent ici avec les deux utilisations dans le même snippet).

Et oui pour l'exemple de fd si tu veux, c'est mieux, sûrement, j'en sais rien je connais pas le contexte système.

Ce que je dis c'est que parfois ça se déduit du contexte, parfois ça peut devenir ambiguë dans certains projets, du coup je me méfie et j'aurais tendance à ne pas être aussi catégorique que toi en disant "maintenant qu'on a nos conventions tout roule".

+3 -0
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