Venant d'un arrière-plan Python, où il y a toujours une «bonne façon de le faire» (une façon «pythonique») en matière de style, je me demande si la même chose existe pour Ruby. J'ai utilisé mes propres règles de style, mais je pense publier mon code source et j'aimerais qu'il adhère à toutes les règles non écrites qui pourraient exister.
Est-ce "The Ruby Way" de taper explicitement return
dans les méthodes? Je l'ai vu faire avec et sans, mais y a-t-il une bonne façon de le faire? Y a-t-il peut-être un bon moment pour le faire? Par exemple:
def some_func(arg1, arg2, etc)
# Do some stuff...
return value # <-- Is the 'return' needed here?
end
ruby
coding-style
return-value
Sasha Chedygov
la source
la source
Réponses:
Ancienne question (et "répondu"), mais je vais jeter mes deux cents en guise de réponse.
TL; DR - Vous n'êtes pas obligé, mais cela peut rendre votre code beaucoup plus clair dans certains cas.
Bien que ne pas utiliser de retour explicite puisse être «à la manière de Ruby», il est déroutant pour les programmeurs travaillant avec du code inconnu ou peu familier avec cette fonctionnalité de Ruby.
C'est un exemple un peu artificiel, mais imaginez avoir une petite fonction comme celle-ci, qui ajoute un au nombre passé et l'assigne à une variable d'instance.
Était-ce censé être une fonction qui retournait une valeur, ou non? Il est vraiment difficile de dire ce que le développeur voulait dire, car il attribue à la fois la variable d'instance et renvoie également la valeur attribuée.
Supposons que beaucoup plus tard, un autre programmeur (peut-être pas très familier avec la façon dont Ruby effectue des retours basés sur la dernière ligne de code exécutée) arrive et veut mettre dans quelques instructions d'impression pour la journalisation, et la fonction devient ceci ...
Maintenant, la fonction est interrompue si quelque chose attend une valeur renvoyée . Si rien n'attend une valeur renvoyée, c'est bien. Clairement, si quelque part plus bas dans la chaîne de code, quelque chose qui appelle ceci attend une valeur renvoyée, il échouera car il ne récupère pas ce qu'il attend.
La vraie question est maintenant la suivante: est-ce que quelque chose s'attendait vraiment à une valeur renvoyée? Cela a-t-il cassé quelque chose ou pas? Va-t-il casser quelque chose dans le futur? Qui sait! Seul un examen complet du code de tous les appels vous le permettra.
Donc, pour moi au moins, la meilleure pratique consiste soit à être très explicite que vous renvoyez quelque chose si cela compte, soit à ne rien renvoyer du tout quand ce n'est pas le cas.
Donc, dans le cas de notre petite fonction de démonstration, en supposant que nous voulions qu'elle renvoie une valeur, elle s'écrirait comme ceci ...
Et il serait très clair pour tout programmeur qu'il renvoie une valeur, et beaucoup plus difficile pour eux de la casser sans s'en rendre compte.
Alternativement, on pourrait l'écrire comme ça et laisser de côté l'instruction return ...
Mais pourquoi se donner la peine d'omettre le mot retour? Pourquoi ne pas simplement le mettre là-dedans et expliquer à 100% ce qui se passe? Cela n'aura littéralement aucun impact sur la capacité de votre code à fonctionner.
la source
return
ajoute une signification sémantique au code, pourquoi pas? Ce n'est guère très verbeux - nous ne parlons pas de 5 lignes contre 3, juste un mot de plus. Je préférerais voirreturn
au moins dans les fonctions (peut-être pas dans des blocs) afin d'exprimer ce que fait réellement le code. Parfois, vous devez retourner à mi-fonction - ne laissez pas le dernierreturn
mot-clé sur la dernière ligne simplement parce que vous le pouvez. Je ne suis pas du tout favorable à la verbosité, mais je privilégie la cohérence.side_effect()
et qu'un autre développeur décide d'utiliser (ab) la valeur de retour implicite de votre procédure. Pour résoudre ce problème, vous pouvez définir vos procédures explicitementreturn nil
.Non. Le bon style Ruby n'utilise généralement qu'un retour explicite pour un retour anticipé . Ruby est grand sur le minimalisme du code / la magie implicite.
Cela dit, si un retour explicite rendrait les choses plus claires ou plus faciles à lire, cela ne nuira à rien.
la source
return
déjà une signification sémantique significative en tant que SORTIE ANTICIPÉE de la fonction.return
sur la dernière ligne avec une sortie anticipée de toute façon?J'utilise personnellement le
return
mot - clé pour faire la distinction entre ce que j'appelle les méthodes fonctionnelles , c'est-à-dire les méthodes qui sont exécutées principalement pour leur valeur de retour, et les méthodes procédurales qui sont exécutées principalement pour leurs effets secondaires. Ainsi, les méthodes dans lesquelles la valeur de retour est importante, obtiennent unreturn
mot clé supplémentaire pour attirer l'attention sur la valeur de retour.J'utilise la même distinction lors de l' appel de méthodes: les méthodes fonctionnelles obtiennent des parenthèses, les méthodes procédurales non.
Et enfin, j'utilise aussi cette distinction avec les blocs: les blocs fonctionnels obtiennent des accolades, les blocs procéduraux (c'est-à-dire les blocs qui "font" quelque chose) obtiennent
do
/end
.Cependant, j'essaie de ne pas être religieux à ce sujet: avec des blocs, des accolades et
do
/end
ont une priorité différente, et plutôt que d'ajouter des parenthèses explicites pour lever l'ambiguïté d'une expression, je passe simplement à l'autre style. Il en va de même pour l'appel de méthode: si l'ajout de parenthèses autour de la liste de paramètres rend le code plus lisible, je le fais, même si la méthode en question est de nature procédurale.la source
En fait, l'important est de faire la distinction entre:
Ruby n'a pas de moyen natif de les distinguer - ce qui vous rend vulnérable à l'écriture d'une procédure
side_effect()
et qu'un autre développeur décide d'abuser de la valeur de retour implicite de votre procédure (en la traitant essentiellement comme une fonction impure).Pour résoudre cela, prenez une feuille du livre de Scala et Haskell et faites revenir explicitement vos procédures
nil
(akaUnit
ou()
dans d'autres langues).Si vous suivez ceci, utiliser
return
ou non une syntaxe explicite devient simplement une question de style personnel.Pour distinguer davantage les fonctions et les procédures:
do/end
()
, tandis que lorsque vous appelez des fonctions, neNotez que Jörg W Mittag préconisait en fait l'inverse - éviter les
()
s pour les procédures - mais ce n'est pas conseillé car vous voulez que les invocations de méthodes à effet secondaire soient clairement distinguables des variables, en particulier lorsque l'arité est égale à 0. Voir le guide de style Scala sur l'invocation de méthode pour détails.la source
function_a
, et que j'aifunction_a
été écrite pour appeler (et que je ne peux fonctionner qu'en appelant)procedure_b
, est-cefunction_a
vraiment une fonction? Il renvoie une valeur, répondant à vos exigences en matière de fonctions, mais il a un effet secondaire, répondant aux exigences des procédures.function_a
pourrait contenir un arbre d'procedure_...
appels, comme en faitprocedure_a
pourrait contenir un arbre d'function_...
appels. Comme Scala mais contrairement à Haskell, il ne peut y avoir aucune garantie dans Ruby qu'une fonction n'a pas d'effet secondaire.Le guide de style indique que vous ne devriez pas utiliser
return
sur votre dernière déclaration. Vous pouvez toujours l'utiliser si ce n'est pas le dernier . C'est l'une des conventions que la communauté suit strictement, et vous devriez le faire si vous prévoyez de collaborer avec quiconque utilise Ruby.Cela étant dit, le principal argument en faveur de l'utilisation de
return
s explicites est qu'il est déroutant pour les personnes venant d'autres langues.Une heuristique courante pour la longueur de méthode (à l'exclusion des getters / setters) en java est un écran . Dans ce cas, il se peut que vous ne voyiez pas la définition de la méthode et / ou que vous ayez déjà oublié d'où vous reveniez.
En revanche, en Ruby, il est préférable de s'en tenir à des méthodes de moins de 10 lignes . Compte tenu de cela, on pourrait se demander pourquoi il doit écrire ~ 10% de déclarations supplémentaires, alors qu'elles sont clairement implicites.
Puisque Ruby n'a pas de méthodes vides et que tout est beaucoup plus concis, vous ajoutez simplement des frais généraux pour aucun des avantages si vous optez pour des
return
s explicites .la source
Je suis d'accord avec Ben Hughes et en désaccord avec Tim Holt, car la question mentionne la manière définitive dont Python le fait et demande si Ruby a une norme similaire.
Cela fait.
C'est une caractéristique si bien connue du langage que quiconque s'attend à déboguer un problème dans ruby devrait raisonnablement être censé le savoir.
la source
return
mot - clé lorsque cela n'est pas nécessaire.C'est une question de style que vous préférez pour la plupart. Vous devez utiliser le mot-clé return si vous souhaitez revenir de quelque part au milieu d'une méthode.
la source
Comme Ben l'a dit. Le fait que «la valeur de retour d'une méthode ruby est la valeur de retour de la dernière instruction dans le corps de la fonction» fait que le mot-clé return est rarement utilisé dans la plupart des méthodes ruby.
la source
if failed_check then nil else @list end
? C'est vraiment fonctionnel .