Est-ce une mauvaise idée de lister chaque argument de fonction / méthode sur une nouvelle ligne et pourquoi?

22

Je travaille avec quelqu'un qui, à chaque fois qu'il appelle une fonction, met les arguments sur une nouvelle ligne, par exemple

aFunction(
    byte1,
    short1,
    int1, 
    int2,
    int3,
    int4,
    int5
) ;

Je trouve cela très ennuyeux car cela signifie que le code n'est pas très compact, donc je dois numériser de plus en plus pour donner un sens à la logique. Je suis intéressé de savoir s'il s'agit réellement d'une mauvaise pratique et si oui, comment puis-je les persuader de ne pas le faire?

Daniel Ball
la source
25
+1, je ne sais pas assez pour répondre à votre question, mais je déteste cela aussi. Cependant, si vous avez autant d'arguments dans une fonction, votre fonction en fait probablement trop.
maple_shaft
28
Plus précisément, pourquoi devons-nous encore voir les préférences de chacun à ce sujet? pourquoi nos IDE ne peuvent-ils pas simplement le présenter automatiquement dans le style que nous voulons?
Alex Feinman
5
Mike, j'aime que le code occupe un minimum d'espace sur l'écran. Mais c'est un compromis. Je mets {sur une ligne séparée car cela facilite la correspondance avec la fermeture} et je comprends correctement la portée du bloc. Cela vaut le compromis de perdre une ligne d'écran.
Brian Schroth
2
@Alex: Vous avez tout à fait raison. Je pense que la bonne chose à faire serait d'avoir une langue où l'arbre d'analyse du code est stocké sur le disque et affiché selon les préférences de l'utilisateur.
Neil G
1
@maple_shaft Je méprise les déclarations comme ça. Non pas parce qu'il n'y a pas de vérité, mais parce que trop de gens suivent de tels conseils sans laisser de place aux nuances.
Stijn

Réponses:

38

C'est juste une directive de codage que vous aimerez ou non. L'important est que vous et vos collègues acceptiez de l'utiliser ou non.

De toute évidence, la meilleure façon d'augmenter la lisibilité est de limiter le nombre d'arguments.

Martin Wickman
la source
24
Trop de gens réduisent les arguments en les déversant dans un tableau. Je préfère voir un désordre laid que du code d'apparence plus propre avec une complexité cachée.
Satanicpuppy
18
Les tableaux ne sont pas la voie à suivre. Il peut y avoir une structure cachée dans les arguments, ou peut-être que la fonction en fait trop et doit être divisée.
Michael K
4
Je trouve que l'utilisation de plusieurs lignes aide à rendre les paramètres IF lisibles par le code sont une expression longue ou un peu trop. Sinon, c'est juste ennuyeux.
PedroC88
3
Les placer dans un objet de transfert de données ne fait que déplacer le problème. Si tous les arguments sont requis, ils doivent tous être des arguments obligatoires du constructeur du DTO, ce qui signifie que vous avez toujours autant d'arguments.
Scott Whitlock
21

C'est une question de préférence. Pour les appels de fonction compliqués où vous voulez documenter chaque paramètre, ou où les variables sont assez longues et il y en a beaucoup, cela peut être bon.

Par exemple:

do_complex_op(
      0, //Starting state, always 0, ask Joe why
      X, //X-coord of thingy
      y, //Y-coord of thingy
      73, //in this case, we don't want to use Z but want constant 
      dlogMessageTitle, //message for dialogue title
      dlogMessageText, //message for dialogue contents, don't care about this.
      SomethingIP, //IP of something-or-other server, can be NULL, won't crash.
      someObject.childObject.getValue(key1).HVAL, //very long path to HVAL
      someObject.childObject.getValue(key1).LVAL, //very long path to LVAL
      this.parentWindow.owner.mainTextBox.text.value.trim, //get the trimmed text, untrimmed text causes weird output
      pvrMainSettingForLongBlahs.getObjectByPath(somePath),
      pvrMainSettingForLongBlahs.K_TCA_UPPER_LIMIT,
      pvrMainSettingForLongBlahs.K_ENDPOINT_COMPLIANCE_LEVEL,
 );

Avec les langages qui autorisent les paramètres nommés, cela est plus courant si vous utilisez les noms de paramètres (l'exemple est en PL / SQL):

PKG_SOME_TEST_CODE.FN_DO_SOMETHING( in_text => 'test text',
                                    in_id => v_id,
                                    in_ref_id => v_ref_id,
                                    out_array_for_storage => v_bArray); 

Mais je suis d'accord avec vous que si l'appel de fonction est simple et pas trop de paramètres, cela pourrait devenir ennuyeux, comme:

setColour (
    r,
    g,
    b
 );

Je trouve beaucoup plus facile à lire

 setColour(r,g,b);

Pour @ammoQ:

rc=a(b,c(d,e(f)))

rc=a(
     b,
     c(
       d,
       e(
         f
        )
      )
    )
FrustratedWithFormsDesigner
la source
11
Le premier exemple est une mauvaise réponse à un problème réel. Pourquoi ne pas utiliser des variables anmes explicites en premier lieu?
deadalnix
@deadalnix: Bon point, nettoyé un peu.
FrustratedWithFormsDesigner
1
Vrai. Cependant, ce n'est pas toujours un problème avec les noms de variables. Cela concerne davantage les noms de variables longs, les arguments avec des valeurs par défaut, etc.
inspectorG4dget
4
Je dirais que la meilleure solution au problème est de refactoriser do_complex_op () afin qu'il prenne une structure en paramètre. Ensuite, vous pouvez le faire do_complex_op(new paramStruct { StartingState = 0, XCoord = xcoord }), puis cela devient auto-documenté et beaucoup plus facile à lire
KallDrexx
1
@KallDrexx: Je suis d'accord, mais parfois, changer le code n'est pas une option, comme quand c'est une fonction dans la bibliothèque de quelqu'un d'autre. Bien sûr, je pourrais en faire un wrapper, mais je devrai encore appeler leur fonction d' origine à un moment donné.
FrustratedWithFormsDesigner
10

Tout ce qui est rare à l'OMI est une mauvaise pratique, à moins que sa supériorité sur le style habituel ne puisse être prouvée positivement. «Question de goût» est une mauvaise excuse pour écrire du code plus difficile à lire que nécessaire pour la majorité des programmeurs, car un jour, une pauvre âme, pas habituée à ce style, devra maintenir ce code.

Il est relativement facile de prouver qu'il est rare, d'afficher la source d'exemples sur MSDN ou des sites similaires, d'afficher de grandes bases de code open source, etc. Afficher la sortie des embellisseurs de code. En fin de compte, montrez comment tout le monde dans votre équipe le fait. N'acceptez pas un mauvais style simplement parce que quelqu'un est trop têtu.

user281377
la source
Hm ... avec cette approche, comment pourrions-nous jamais introduire une nouvelle meilleure pratique (ou, grammaticalement correcte: une meilleure pratique )?
Treb
2
Treb: Bien sûr, montrez simplement que la meilleure pratique est en fait meilleure , pas seulement différente .
user281377
4
Mais "plus difficile à lire" est, en soi, subjectif et une question d'opinion. Pour moi, un argument par ligne est plus facile à analyser visuellement que deux, trois ou quatre arguments par ligne. Et je divise toujours un appel en plusieurs lignes s'il dépasse la marque des 100 caractères environ dans l'éditeur.
Toby
2
Meh. «Plus difficile à lire» peut être mesuré objectivement. Cela a tendance à ne pas l'être. En discuter est plus amusant.
JasonTrue
1
il peut être mesuré objectivement mais pas indépendamment de la personne qui fait la lecture.
jk.
9

Eh bien, voici quelques appâts downvote. Je n'ai jamais été accusé d'avoir fait le truc populaire. De toute évidence, si les choses tiennent sur une seule ligne, alors très bien, faites-les sur une seule ligne.

Mais ma principale préoccupation n'est pas de savoir si le code est "moche" ou "joli". Ma principale préoccupation est de savoir à quel point il est facile de comprendre et d'apporter des modifications sans commettre d'erreurs.

Si les arguments sont longs et nombreux, pourquoi ne pas les mettre sur des lignes distinctes? À mon avis, cela permet de voir plus facilement ce qu'elles sont et de les changer plus facilement si nécessaire. Cela me permet également de joindre un commentaire à chaque argument si je le souhaite.

Je souhaite également minimiser le risque de faire une erreur si j'ajoute ou supprime un argument à une fonction, ce qui est plus susceptible de se produire à la fin d'une liste d'arguments qu'au début. Pour cette raison, je préfère mettre la virgule (,) au début d'une ligne plutôt qu'à la fin. Ensuite, si par exemple, je veux supprimer ou ajouter un argument à la fin de la liste, c'est une modification sur une ligne. Je n'ai pas besoin de jouer avec la virgule qui doit aller à la fin de toutes les lignes sauf la dernière, où la dernière doit se terminer par une parenthèse.

Donc (garçon, je vais être flambé pour ça) Je l'écris comme ceci:

nameOfFunction(firstArgument
    , secondArgument // optional comment
       ...
    , lastArgument   // optional comment
    );

Quand il y a une fonction avec de cinq à vingt arguments, la fonction n'a pas réussi de cette façon d'un coup. Il a grandi au fil du temps, ce qui signifie qu'il y a eu beaucoup de modifications. Toute modification non terminée est une erreur de syntaxe ou un bogue. Je ne prétends donc pas que ce soit joli. Je prétends que cela aide à obtenir les bonnes modifications.

(Et pour ceux qui disent que je devrais passer une structure à la place, tout ce qui se passe, c'est déplacer le problème, car vous avez besoin d'un tas de lignes de code pour remplir la structure, sans parler du code supplémentaire pour le déclarer et l'allouer.)

Mike Dunlavey
la source
1
Personnellement, je pense que c'est une excellente réponse car vous avez très bien expliqué votre raisonnement. Bon travail Mike.
Jordan
8

Je ne l'appellerais pas non plus. La meilleure pratique où j'ai travaillé a généralement été de faire en sorte que les appels de fonction soient tous sur une seule ligne, à moins que vous n'ayez à faire défiler horizontalement une quantité importante pour voir l'appel entier. C'est un jugement, mais je dirais certainement que mettre toutes les fonctions comme celle-ci est hors de propos, à moins que ce soit la norme établie par votre organisation.

C'est pourquoi il est de bonne pratique pour une organisation d'établir un ensemble de guides auxquels tous les programmeurs doivent adhérer. Il s'agit de cohérence et de lisibilité.

Orties de Jarrod
la source
5

Cela facilite:

  • Réorganisez les arguments.
  • Mettez en commentaire ou désactivez les arguments.
  • Voir exactement quel argument a changé lorsque vous affichez des différences dans votre système de contrôle de version
  • Évitez de tout ré-indenter et d'habillage de mots lorsque vous ajoutez ou supprimez un argument, ou modifiez le nom de la fonction. (Même si votre éditeur met automatiquement en retrait, vous créez toujours de nombreuses modifications inutiles des espaces blancs qui rendent plus difficile le suivi des modifications dans votre système de contrôle de version.)
Graham Borland
la source
4

Je dirais que les appels de fonction devraient être tous sur une seule ligne, à moins qu'ils ne dépassent considérablement la largeur de votre code standard (souvent 80 caractères, souvent une cause d'arguments :-).

Je ne vois aucun avantage à ce style. Il a l'air subjectivement laid, et je trouve cela pénible lors de la recherche de code. Par exemple, vous souhaiterez peut-être rechercher rapidement et voir si la fonction est jamais appelée avec un certain paramètre passé comme NULL. C'est facile visuellement lorsque tous les paramètres sont sur une seule ligne, et plus difficile quand ils sont divisés comme ceci.

Luke Graham
la source
Cette chose de 80 caractères doit disparaître, il n'y a tout simplement plus de raisons techniquement valables. Nous vivons maintenant dans une ère de moniteurs 19xx X 16xx et de polices réglables ET de tailles de police.
Anon
4
@anon: Des raisons valables pour cela? Pourquoi pensez-vous que le texte est imprimé en colonnes et que les livres sont plus étroits qu'ils ne pourraient l'être? Parce que l'œil humain perd sa trace lors de la lecture sur de très longues lignes.
Zan Lynx
4
@anon: J'aime aussi utiliser mon écran large pour ouvrir deux ou trois fichiers dans une division horizontale qui revient à 80-100 caractères sur une ligne.
Zan Lynx du
4
@anon: Techniquement non, pratiquement: enfer OUI. Zan Lynx a tout à fait raison, et il y a des raisons supplémentaires: fusion, diff, utilisation des utilitaires de ligne de commande ... Oh et bonne chance en se concentrant sur la police 8p à mesure que vous vieillirez: o)
MaR
3

J'ai souvent vu ce style sur les déclarations de fonction ou les définitions , mais jamais sur un appel (jusqu'à présent). Là, cela a parfois du sens car il vous permet d'ajouter plus clairement un commentaire pour les paramètres individuels. Il semble qu'il ait copié ce style dans les appels sans vraiment connaître les raisons sous-jacentes. Vous avez un bon argument contre et il ne semble pas en avoir un bon, alors vous avez mon vote, mais ce n'est pas moi que vous devez convaincre.

Karl Bielefeldt
la source
Je vois les deux sur les appels. Si la liste des paramètres est trop longue, elle doit être répartie sur plusieurs lignes. Si les paramètres ne se regroupent pas normalement dans les limites de largeur, je m'attends à ce qu'ils soient sur des lignes distinctes. Si les noms de fonction et de paramètre correspondent bien sur une seule ligne, je les vois souvent disposés de cette façon.
BillThor
2

Est-ce contraire aux normes de codage de l'entreprise?

Sinon, lancez une discussion sur les normes et ce que les gens aimeraient voir changer. Assurez-vous de mentionner cela comme l'une des choses que vous aimeriez changer.

Ayez une discussion approfondie sur les raisons pour lesquelles vous ne pensez pas que cela est utile et j'espère que vous gagnerez la journée. Vous ne savez jamais que votre collègue pourrait vous convaincre que son chemin est le meilleur après tout;)

Une fois que vous avez une norme mise à jour, il est documenté sur ce que tout le monde devrait coder, donc si votre collègue persiste à le faire, vous pouvez le soulever dans ses révisions de code.

ChrisF
la source
2

Cela peut vous sembler génial, mais cela facilite le travail sur le code. Lors de la refactorisation, vous pouvez commenter les arguments individuels très facilement et vérifier votre refactoriseur avant de supprimer les éléments. Vous pouvez également commenter et remplacer temporairement des types assez facilement.

Il est également plus facile à lire que:

int f(int, int, int,
      char, double, int
      X const&, Y)
{}

Je ne suis pas allé aussi extrême que vous le montrez (car il n'y a pas de noms sur les paramètres, il n'est pas beaucoup utilisé), mais j'ai pris l'habitude de diviser chaque paramètre sur sa propre ligne ou de ne pas le faire du tout.

La partie importante est que votre code peut être imprimé ou affiché sur des écrans standard de 80 couleurs et être toujours lisible.

Edward Strange
la source
2

Vous obtiendrez rarement une réponse honnête d'un programmeur pour quelque chose comme ça. Chacun répondra simplement par ce qu'il fait ou ne préfère pas. La vérité est que, même si nous nous débattons tous parfois, la seule "mauvaise pratique" ici est votre propre inflexibilité.

Vous devez être brutalement honnête avec vous-même pour pouvoir distinguer entre les choses qui sont réellement mauvaises et les choses qui vous ennuient. La vérité est qu'en C / C ++ et langages similaires, vous trouverez rarement une pratique d'indentation qui a un effet tangible sur la compréhensibilité du code. La plupart des discussions au sujet de ce genre de choses ont simplement empilé les deux côtés avec des gens faisant des arguments ridicules et malhonnêtes pour essayer de justifier leur propre préférence personnelle.

Ce qui à ma lecture ... est exactement ce que vous demandez dans cette question: un argument ridicule et fallacieux pour justifier votre préférence personnelle.

Dan Olson
la source
0

Pour être honnête, cela dépend de la personne .. Je dirais que pour les fonctions complexes comme démontré par FrustratedWithForms premier exemple, alors oui; sinon un gros NON. Là encore, c'est pourquoi je préfère appliquer arbitrairement la fonctionnalité IDE du code.

Dark Star1
la source
0

"Je suis intéressé de savoir si c'est vraiment une mauvaise pratique ..."

Oui, c'est une mauvaise pratique, sauf lorsque la liste des variables est anormalement longue. Mais dans ce cas, le problème est probablement dû à la conception de la fonction. Pourquoi ne pas passer un objet qui encapsule de nombreux paramètres?

"... et si oui, comment puis-je les persuader de ne pas le faire?"

Attachez-les et continuez à les chatouiller jusqu'à ce qu'ils acceptent d'arrêter cette merde.

ybakos
la source
"Pourquoi ne pas passer un objet qui encapsule de nombreux paramètres?" OK, vous avez maintenant déplacé le problème vers ce nouvel objet. Il a toujours besoin de la même quantité de paramètres (via son constructeur, par exemple), vous avez donc toujours le même problème.
Stijn
-2

Pourquoi gaspillez-vous des cycles sur une préoccupation aussi banale? Lancez simplement votre fidèle IDE, ouvrez le fichier et reformatez. Voila! Ce sera sous la forme que vous voulez.

Passons maintenant à la question vraiment importante - vi ou emacs, LOL.

SnoopDougieDoug
la source
Et puis quand vous venez de vérifier cela dans le contrôle de code source?
pdr
-2

Je dirais que si les arguments tiennent sur une seule ligne, faites-le. Sinon, un argument par ligne permet une grande lisibilité.

foo(arg1, arg2, arg3, arg4, arg5)

contre.

foo(
    arg1=arg1,
    arg2=arg2,
    arg3=arg3,
    arg4=arg4,
    arg5=arg5,
    arg6=arg6,
    arg7=arg7
)
user271413
la source
3
cela ne semble pas offrir quoi que ce soit de substantiel par rapport aux points soulevés et expliqués dans les 14 réponses précédentes
gnat