Question

Venant d'un arrière-plan Python, où il y a toujours une "bonne façon de le faire" (une manière "pythonique") en ce qui concerne le style, je me demande si la même chose existe pour Ruby. J'utilise mes propres règles de style mais je pense publier mon code source et j'aimerais qu'il respecte toutes les règles non écrites qui pourraient exister.

S'agit-il de "The Ruby Way"? 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 moment opportun pour le faire? Par exemple:

def some_func(arg1, arg2, etc)
  # Do some stuff...
  return value # <-- Is the 'return' needed here?
end
Était-ce utile?

La solution

Ancienne question (et "réponse"), mais je vais ajouter mes deux sous comme réponse.

TL; DR - Ce n’est pas une obligation, mais cela peut rendre votre code beaucoup plus clair dans certains cas.

Bien que le fait de ne pas utiliser de déclaration explicite puisse être "à la manière de Ruby", cela déroute les programmeurs qui travaillent avec du code inconnu ou qui ne connaît pas cette fonctionnalité de Ruby.

C'est un exemple quelque peu artificiel, mais la création d'image a une petite fonction comme celle-ci, qui ajoute un au nombre transmis et l'attribue à une variable d'instance.

def plus_one_to_y(x)
    @y = x + 1
end

S'agissait-il d'une fonction renvoyant une valeur ou non? Il est très difficile de dire ce que le développeur voulait dire, car il attribue la variable d'instance ET renvoie également la valeur attribuée.

Supposons que bien plus tard, un autre programmeur (qui ne sait peut-être pas comment Ruby retourne en fonction de la dernière ligne de code exécutée) arrive et souhaite insérer des instructions d'impression pour la journalisation, et la fonction devient ainsi ...

def plus_one_to_y(x)
    @y = x + 1
    puts "In plus_one_to_y"
end

La fonction est cassée si quelque chose attend une valeur renvoyée . Si rien n'attend une valeur renvoyée, c'est bon. Il est clair que si quelque part plus loin dans la chaîne de code, quelque chose qui appelle cela attend une valeur renvoyée, cela va échouer car il ne récupère pas ce qu'il attend.

La vraie question est la suivante: est-ce que quelque chose attendait vraiment une valeur renvoyée? Est-ce que cela a cassé quelque chose ou pas? Est-ce que ça casse quelque chose dans le futur? Qui sait! Seule une vérification complète du code de tous les appels vous le fera savoir.

Donc pour moi du moins, la meilleure approche consiste à indiquer très clairement que vous retournez quelque chose si cela compte, ou à ne rien renvoyer si 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, ce serait écrit comme ceci ...

def plus_one_to_y(x)
    @y = x + 1
    puts "In plus_one_to_y"
    return @y
end

Et il est très clair pour tout programmeur qu'il renvoie une valeur et qu'il leur est beaucoup plus difficile de la casser sans s'en rendre compte.

Alternativement, on pourrait l'écrire comme ceci et laisser de côté la déclaration de retour ...

def plus_one_to_y(x)
    @y = x + 1
    puts "In plus_one_to_y"
    @y
end

Mais pourquoi se donner la peine d’omettre le mot return? Pourquoi ne pas simplement le préciser et expliquer à 100% ce qui se passe? Cela n'aura littéralement aucun impact sur la capacité de votre code à s'exécuter.

Autres conseils

Non. Un bon style Ruby n’utilise généralement qu’un retour explicite pour un retour anticipé . Ruby aime beaucoup le minimalisme de code et la magie implicite.

Cela dit, si un retour explicite rendait les choses plus claires ou plus faciles à lire, cela ne nuirait à rien.

J'utilise personnellement le mot clé return pour distinguer ce que j'appelle les méthodes fonctionnelles , c'est-à-dire les méthodes exécutées principalement pour leur valeur de retour et les méthodes procédurales qui sont exécutés principalement pour leurs effets secondaires. Ainsi, pour les méthodes dans lesquelles la valeur de retour est importante, obtenez un mot clé supplémentaire return pour attirer l'attention sur la valeur de retour.

J'utilise la même distinction lorsque en appelant : les méthodes fonctionnelles ont des parenthèses, pas les méthodes procédurales.

Enfin, j’utilise également cette distinction avec les blocs: les blocs fonctionnels ont des accolades, les blocs procéduraux (c’est-à-dire les blocs qui "font quelque chose") obtiennent font / end .

Cependant, j'essaie de ne pas être religieux: avec des blocs, des accolades et do / end ont une priorité différente, et plutôt que d'ajouter des parenthèses explicites expression, je viens de passer à 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.

En réalité, l’important est de distinguer entre:

  1. Fonctions - méthodes exécutées pour leur valeur de retour
  2. Procédures - méthodes exécutées pour leurs effets secondaires

Ruby n’a pas de méthode native pour les distinguer - ce qui vous laisse vulnérable à l’écriture d’une procédure side_effect () et à un autre développeur qui décide d’abuser de la valeur de retour implicite de votre procédure (en le traitant comme une fonction impure).

Pour résoudre ce problème, reprenez le livre de Scala et Haskell et demandez à vos procédures de renvoyer explicitement nil (autrement dit Unité ou () dans d'autres langues).

Si vous suivez cela, alors utiliser la syntaxe return explicite ou non devient simplement une question de style personnel.

Pour mieux distinguer les fonctions et les procédures:

  1. Copiez la belle idée de Jörg W Mittag d’écrire des blocs fonctionnels avec des accolades et des blocs procéduraux avec do / end
  2. Lorsque vous appelez des procédures, utilisez () , alors que lorsque vous appelez des fonctions, ne pas

Notez que Jörg W Mittag a en fait préconisé l’inverse - en évitant les () pour les procédures - mais cela n’est pas conseillé, car vous voulez que les invocations de méthodes à effet secondaire soient clairement distinctes des variables, en particulier lorsque l'arité est égal à 0. Consultez le guide de style Scala sur l'invocation de méthode pour plus de détails.

Le guide de style indique qu'il ne faut pas ' Ne pas utiliser return sur votre dernière déclaration. Vous pouvez toujours l'utiliser s'il ne s'agit pas du dernier . C’est l’une des conventions que la communauté respecte strictement, et vous devriez en faire de même si vous envisagez de collaborer avec toute personne utilisant Ruby.

Cela étant dit, le principal argument en faveur de l'utilisation de return s explicites est qu'il est source de confusion pour les personnes venant d'autres langues.

  • Tout d’abord, cela n’est pas entièrement exclusif à Ruby. Par exemple, Perl a aussi des retours implicites.
  • Deuxièmement, la majorité des personnes concernées sont des langues algol. La plupart d'entre eux sont "inférieurs" à Ruby, vous devez donc écrire plus de code pour faire quelque chose.

Une heuristique commune pour la longueur de la méthode (à l’exclusion des getters / setters) en java est un écran . Dans ce cas, vous risquez de ne pas voir la définition de la méthode et / ou d’avoir déjà oublié votre lieu de retour.

D'autre part, en Ruby, il est préférable de s'en tenir aux méthodes moins plus de 10 lignes . Compte tenu de cela, on se demanderait pourquoi il doit écrire environ 10% de plus de déclarations, alors qu'elles sont clairement impliquées.

Puisque Ruby n’a pas de méthodes void et que tout est beaucoup plus concis, vous n’ajoutez de la surcharge pour aucun des avantages si vous utilisez des retours explicites. .

Je suis d’accord avec Ben Hughes et 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 se produit.

C’est une caractéristique du langage si bien connue que quiconque s’attend à déboguer un problème lié à ruby ??devrait raisonnablement s’attendre à le connaître.

La question est de savoir quel style vous préférez pour la plupart. Vous devez utiliser le mot-clé return si vous voulez retourner quelque part au milieu d'une méthode.

Comme Ben a dit. Le fait que "la valeur de retour d'une méthode ruby ??soit la valeur de retour de la dernière instruction du corps de la fonction" fait que le mot clé de retour est rarement utilisé dans la plupart des méthodes ruby.

def some_func_which_returns_a_list( x, y, z)
  return nil if failed_some_early_check


  # function code 

  @list     # returns the list
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top