J'ai un collègue qui essaie activement de me convaincre que je ne devrais pas utiliser do..end et utiliser à la place des accolades pour définir des blocs multilignes dans Ruby.
Je suis fermement dans le camp de n'utiliser que des accolades bouclées pour les courtes one-liners et je ne ... finis pour tout le reste. Mais j'ai pensé que je contacterais la communauté dans son ensemble pour obtenir une solution.
Alors, de quoi s'agit-il et pourquoi? (Exemple de code shoulda)
context do
setup { do_some_setup() }
should "do somthing" do
# some more code...
end
end
ou
context {
setup { do_some_setup() }
should("do somthing") {
# some more code...
}
}
Personnellement, le simple fait de regarder ce qui précède répond à la question pour moi, mais je voulais ouvrir cela à la plus grande communauté.
ruby-on-rails
ruby
ruby-on-rails-3
coding-style
Blake Taylor
la source
la source
Réponses:
La convention générale consiste à utiliser do..end pour les blocs multilignes et les accolades pour les blocs à une seule ligne, mais il existe également une différence entre les deux qui peut être illustrée par cet exemple:
Cela signifie que {} a une priorité plus élevée que do..end, alors gardez cela à l'esprit lorsque vous décidez de ce que vous voulez utiliser.
PS: Encore un exemple à garder à l'esprit pendant que vous développez vos préférences.
Le code suivant:
signifie vraiment:
Et ce code:
signifie vraiment:
Donc, pour obtenir la définition réelle que vous voulez, avec des accolades, vous devez faire:
Peut-être que l'utilisation d'accolades pour les paramètres est quelque chose que vous voulez faire de toute façon, mais si vous ne le faites pas, il est probablement préférable d'utiliser do..end dans ces cas pour éviter cette confusion.
la source
puts [1,2,3].map do |k| k+1; end
n'imprime que l'énumérateur, c'est-à-dire une chose. Est-ce que met pas passé deux arguments ici à savoir[1,2,3].map
etdo |k| k+1; end
?Depuis Programming Ruby :
Donc le code
Lie le bloc à la
param
variable tandis que le codeLie le bloc à la fonction
f
.Cependant, ce n'est pas un problème si vous mettez les arguments de fonction entre parenthèses.
la source
Il y a quelques points de vue là-dessus, c'est vraiment une question de préférence personnelle. De nombreux rubisistes adoptent l'approche que vous faites. Cependant, deux autres styles communs consistent à toujours utiliser l'un ou l'autre, ou à utiliser
{}
pour les blocs qui renvoient des valeurs etdo ... end
pour les blocs qui sont exécutés pour les effets secondaires.la source
Il y a un avantage majeur aux accolades: de nombreux éditeurs ont beaucoup plus de facilité à les faire correspondre, ce qui facilite beaucoup certains types de débogage. Pendant ce temps, le mot-clé "do ... end" est un peu plus difficile à trouver, d'autant plus que "end" correspond également aux "if".
la source
do ... end
mots-clés par défautdo ... end
s'agit d'un cas particulier qui nécessite une logique spécifique au langage.La règle la plus courante que j'ai vue (la plus récemment dans Eloquent Ruby ) est:
la source
Je vote pour faire / terminer
La convention est
do .. end
pour multiligne et{ ... }
aux monoplaces.Mais j'aime
do .. end
mieux, donc quand j'ai un one liner, je l'utilisedo .. end
quand même mais je le formate comme d'habitude pour faire / finir en trois lignes. Cela rend tout le monde heureux.Un problème avec
{ }
est qu'il est hostile au mode poésie (car ils se lient étroitement au dernier paramètre et non à l'appel de méthode entier, vous devez donc inclure des parens de méthode) et ils ne sont pas aussi beaux, à mon avis. Ce ne sont pas des groupes d'instructions et ils entrent en conflit avec les constantes de hachage pour la lisibilité.De plus, j'en ai assez vu
{ }
dans les programmes C. La manière de Ruby, comme d'habitude, est meilleure. Il existe exactement un type deif
bloc, et vous n'avez jamais à revenir en arrière et à convertir une instruction en une instruction composée.la source
do_stuff if x==1
), qui est assez ennuyeux à convertir en syntaxe normale. Mais c'est une autre discussion.if
, un suffixeif
, un suffixeunless
(également une sorte deif
, un sinon) et une ligneif
avecthen
. La méthode Ruby est d'avoir de nombreuses façons d'exprimer en fait quelque chose qui est toujours la même chose, bien pire que ce que propose C qui suit des règles très simples et strictes.Quelques rubisistes influents suggèrent d'utiliser des accolades lorsque vous utilisez la valeur de retour, et do / end quand vous ne le faites pas.
http://talklikeaduck.denhaven2.com/2007/10/02/ruby-blocks-do-or-brace (sur archive.org)
http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc (sur archive.org)
Cela semble être une bonne pratique en général.
Je modifierais un peu ce principe pour dire que vous devriez éviter d'utiliser do / end sur une seule ligne car c'est plus difficile à lire.
Vous devez être plus prudent en utilisant des accolades car cela se liera au paramètre final d'une méthode au lieu de l'appel entier de la méthode. Ajoutez simplement des parenthèses pour éviter cela.
la source
En fait, c'est une préférence personnelle, mais cela dit, au cours des 3 dernières années de mes expériences avec le rubis, j'ai appris que le rubis a son style.
Un exemple serait, si vous venez d'un arrière-plan JAVA, pour une méthode booléenne que vous pourriez utiliser
remarquez le cas du chameau et le plus souvent le préfixe «est» pour l'identifier comme une méthode booléenne.
Mais dans le monde des rubis, la même méthode serait
donc je pense personnellement qu'il vaut mieux aller avec 'ruby way' (mais je sais qu'il faut du temps pour que quelqu'un comprenne (cela m'a pris environ 1 an: D)).
Enfin, j'irais avec
blocs.
la source
J'ai mis une autre réponse, bien que la grande différence ait déjà été signalée (précedence / binding), et que cela peut poser des problèmes difficiles à trouver (le Tin Man, et d'autres l'ont souligné). Je pense que mon exemple montre le problème avec un extrait de code pas si habituel, même les programmeurs expérimentés ne lisent pas comme les dimanches:
Ensuite, j'ai fait du code embellissant ...
si vous changez
{}
ici,do/end
vous obtiendrez l'erreur, cette méthodetranslate
n'existe pas ...Pourquoi cela se produit est souligné ici plus d'un - la préséance. Mais où mettre des accolades ici? (@the Tin Man: j'utilise toujours des accolades, comme vous, mais ici ... supervisé)
donc chaque réponse comme
est tout simplement faux s'il est utilisé sans le "MAIS Gardez un œil sur les accolades / priorité!"
encore:
et
(ce que fait le résultat de extend avec le bloc ...)
Donc, si vous voulez utiliser do / end, utilisez ceci:
la source
Se résume à un préjugé personnel, je préfère les accolades à un bloc do / end car il est plus compréhensible pour un plus grand nombre de développeurs en raison de la majorité des langages d'arrière-plan les utilisent sur la convention do / end. Cela étant dit, la vraie clé est de parvenir à un accord au sein de votre boutique, si do / end est utilisé par 6/10 développeurs que TOUT LE MONDE devrait les utiliser, si 6/10 utilisent des accolades, alors tenez-vous-en à ce paradigme.
Il s'agit de créer un modèle afin que l'équipe dans son ensemble puisse identifier les structures de code plus rapidement.
la source
Il y a une différence subtile entre eux, mais {} lie plus étroitement que do / end.
la source
Mon style personnel est de mettre l'accent sur la lisibilité plutôt que sur des règles rigides de choix
{
...}
vsdo
...end
, lorsqu'un tel choix est possible. Mon idée de la lisibilité est la suivante:Dans une syntaxe plus complexe, telle que les blocs imbriqués multilignes, j'essaie d'intercaler les délimiteurs
{
...}
etdo
...end
pour le résultat le plus naturel, par exemple.Bien que l'absence de règles rigides puisse produire des choix légèrement différents pour différents programmeurs, je pense que l'optimisation au cas par cas pour la lisibilité, bien que subjective, est un net gain par rapport au respect de règles rigides.
la source
Ruby
c'était le meilleur langage pragmatique qui soit. Dois-je dire langage de script. Aujourd'hui, je pense que vous seriez tout aussi bien d'apprendreBrainfuck
.J'ai pris un exemple de la réponse la plus votée ici. Dire,
Si vous vérifiez quelle implémentation interne dans array.rb, l'en-tête de la méthode map dit :
Invokes the given block once for each element of self.
c'est-à-dire qu'il accepte un bloc de code - tout ce qui se trouve entre do et end est exécuté comme yield. Ensuite, le résultat sera à nouveau collecté sous forme de tableau, ce qui retournera un objet complètement nouveau.
la source
Il y a une troisième option: écrire un préprocesseur pour déduire "fin" sur sa propre ligne, à partir de l'indentation. Les penseurs profonds qui préfèrent un code concis ont raison.
Mieux encore, piratez ruby donc c'est un drapeau.
Bien sûr, la solution la plus simple "choisissez vos combats" est d'adopter la convention de style selon laquelle une séquence d'extrémités apparaîtra toutes sur la même ligne et d'apprendre à votre coloration syntaxique pour les désactiver. Pour faciliter l'édition, on pourrait utiliser des scripts d'éditeur pour développer / réduire ces séquences.
20% à 25% de mes lignes de code ruby sont "fin" sur leur propre ligne, toutes déduites de manière triviale par mes conventions d'indentation. Ruby est le langage de type lisp à avoir remporté le plus grand succès. Quand les gens contestent cela, demandant où sont toutes les horribles parenthèses, je leur montre une fonction rubis se terminant par sept lignes de "fin" superflues.
J'ai codé pendant des années en utilisant un préprocesseur lisp pour déduire la plupart des parenthèses: Une barre '|' ouvert un groupe qui se fermait automatiquement à la fin de la ligne, et un signe dollar «$» servait d'espace réservé vide où il n'y aurait autrement aucun symbole pour aider à déduire les regroupements. C'est bien sûr un territoire de guerre religieuse. Lisp / schéma sans les parenthèses est le plus poétique de tous les langages. Pourtant, il est plus facile de réduire simplement les parenthèses à l'aide de la coloration syntaxique.
Je code toujours avec un préprocesseur pour Haskell, pour ajouter des heredocs, et pour par défaut toutes les lignes de vidage en tant que commentaires, tout en retrait en tant que code. Je n'aime pas les personnages de commentaires, quelle que soit la langue.
la source