├── .gitattributes
├── README-frFR.md
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.md whitespace=trailing-space,tab-in-indent
2 |
--------------------------------------------------------------------------------
/README-frFR.md:
--------------------------------------------------------------------------------
1 | # Préambule
2 |
3 | > Le style est ce qui sépare le bon de l'excellent.
4 | > -- Bozhidar Batsov
5 |
6 | Une chose m'a toujours gêné en tant que développeur Ruby - les développeurs
7 | Python ont une super référence de style de programmation
8 | ([PEP-8](http://www.python.org/dev/peps/pep-0008/)) alors que nous n'avons
9 | jamais eu un tel guide officiel, définissant le style et les bonnes pratiques
10 | de programmation Ruby. Et je pense que le style compte. Je pense également
11 | que des gens biens, tels que nous, développeurs Ruby, devraient être
12 | tout à fait capables de produire ce document convoité.
13 |
14 | Ce guide (écrit par votre serviteur) a vu le jour en tant que convention de
15 | programmation Ruby interne à notre entreprise. Au bout d'un certain temps,
16 | il m'a semblé que ce travail pourrait s'avérer intéressant pour les membres
17 | de la communauté ruby en général et que le monde n'avait pas vraiment besoin
18 | d'une convention de programmation interne de plus. Mais le monde pourrait
19 | certainement tirer profit d'un ensemble de pratiques, d'idiomes et de conseils
20 | de style pour la programmation Ruby.
21 |
22 | Dès le lancement de ce guide, j'ai reçu énormément de retours des membres de
23 | l'exceptionnelle communauté Ruby à travers le monde. Merci pour toutes les
24 | suggestions et votre soutien! Ensemble, nous pouvons créer une ressource
25 | bénéfique à tous les développeurs Ruby ici présents.
26 |
27 | Au fait, si vous faites du Rails, vous pouvez consulter le
28 | [Guide de style Ruby on Rails 3](https://github.com/bbatsov/rails-style-guide) complémentaire.
29 |
30 | # Le guide de style Ruby
31 |
32 | Ce guide de style Ruby recommande des bonnes pratiques conçues pour qu'un
33 | programmeur Ruby du monde réel puisse produire un code qui puisse être
34 | maintenu par d'autres programmeurs Ruby du monde réel. Un guide de style qui
35 | reflète les utilisations du monde réel est utilisé, et un guide de style qui
36 | repose sur un idéal qui a été rejeté par les personnes qu'il est censé aider
37 | a de bonnes chances de ne pas être utilisé du tout – peu importe sa qualité.
38 |
39 | Le guide est divisé en plusieurs sections de règles connexes. J'ai essayé
40 | d'ajouter le rationnel derrière les règles (j'ai omis certains points que je
41 | considérais plutôt évidents).
42 |
43 | Ces règles ne sont pas sorties de nulle part - la majeure partie est basée sur
44 | ma longue carrière d'ingénieur logiciel, les retours et les suggestions des membres
45 | de la communauté Ruby et diverses ressources très renommées sur la programmation
46 | Ruby, telles que ["Programming Ruby 1.9"](http://pragprog.com/book/ruby3/programming-ruby-1-9)
47 | et ["The Ruby Programming Language"](http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177).
48 |
49 | Ce guide est toujours un travail en cours - certaines règles n'ont pas d'exemple,
50 | d'autres ont des exemples qui ne les illustre pas assez clairement. Ces problèmes
51 | seront corrigés tôt ou tard - gardez les juste à l'esprit pour l'instant.
52 |
53 | Vous pouvez générer une copie PDF ou HTML de ce guide en utilisant
54 | [Transmuter](https://github.com/TechnoGate/transmuter).
55 |
56 | Le projet [rubocop](https://github.com/bbatsov/rubocop) vise à fournir un moyen
57 | automatisé pour vérifier si un code Ruby est conforme avec le guide de style.
58 | Pour l'instant, il est loin d'être prêt pour la production et il lui manque
59 | beaucoup de fonctionnalités. Naturellement, tout le monde est invité à participer
60 | à son amélioration!
61 |
62 | Des traductions de ce guide sont disponibles dans les langues suivantes :
63 |
64 | * [Anglais](https://github.com/bbatsov/ruby-style-guide/blob/master/README.md) (version originale)
65 | * [Chinois simplifié](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhCN.md)
66 | * [Chinois traditionnel](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhTW.md)
67 |
68 | ## Table des matières
69 |
70 | * [Structure du code source](#structure-du-code-source)
71 | * [Syntaxe](#syntaxe)
72 | * [Nommage](#nommage)
73 | * [Commentaires](#commentaires)
74 | * [Commentaires d'annotation](#commentaires-dannotation)
75 | * [Classes](#classes)
76 | * [Exceptions](#exceptions)
77 | * [Collections](#collections)
78 | * [Chaînes de caractères](#chaines-de-caractères)
79 | * [Expressions rationnelles](#expressions-rationnelles)
80 | * [Notations pourcents](#notations-pourcents)
81 | * [Méta-programmation](#méta-programmation)
82 | * [Divers](#divers)
83 |
84 | ## Structure du code source
85 |
86 | > Chacun de nous ou presque est convaincu que tous les styles sauf le notre sont
87 | > moches et illisibles. Retirez "sauf le notre" et nous aurons probablement
88 | > raison...
89 | > -- Jerry Coffin (à propos de l'indentation)
90 |
91 | * Utilisez l'`UTF-8` comme encodage des fichiers source.
92 | * Utilisez deux **espaces** par niveau d'indentation. Pas de tabulation.
93 |
94 | ```Ruby
95 | # bien
96 | def some_method
97 | do_something
98 | end
99 |
100 | # mauvais - quatre espaces
101 | def some_method
102 | do_something
103 | end
104 | ```
105 |
106 | * Utilisez des fins de ligne de type Unix. (*Les utilisateurs BSD/Solaris/Linux/OSX sont couverts par défaut,
107 | les utilisateurs Windows doivent faire très attention.)
108 | * Si vous utilisez Git, vous pouvez ajouter les paramètres de configuration
109 | suivants pour protéger votre projet des fins de ligne Windows qui traîneraient:
110 |
111 | $ git config --global core.autocrlf true
112 |
113 | * Utilisez des espaces autour des opérateurs, après les deux points, points-virgules et virgules,
114 | autour de `{` et devant `}`. L'espace est (généralement) sans importance pour
115 | l'interpréteur Ruby, mais l'utiliser correctement permet d'écrire facilement du code lisible.
116 |
117 | ```Ruby
118 | sum = 1 + 2
119 | a, b = 1, 2
120 | 1 > 2 ? true : false; puts 'Hi'
121 | [1, 2, 3].each { |e| puts e }
122 | ```
123 |
124 | L'opérateur d'exposant est la seule exception:
125 |
126 | ```Ruby
127 | # mauvais
128 | e = M * c ** 2
129 |
130 | # bien
131 | e = M * c**2
132 | ```
133 |
134 | * Pas d'espace après `(`, `[` ou devant `]`, `)`.
135 |
136 | ```Ruby
137 | some(arg).other
138 | [1, 2, 3].length
139 | ```
140 |
141 | * Indenter `when` au même niveau que `case`. Je sais que beaucoup
142 | seront en désaccord avec cette règle, mais c'est un style établi
143 | dans "The Ruby Programming Language" et "Programming Ruby".
144 |
145 | ```Ruby
146 | case
147 | when song.name == 'Misty'
148 | puts 'Not again!'
149 | when song.duration > 120
150 | puts 'Too long!'
151 | when Time.now.hour > 21
152 | puts "It's too late"
153 | else
154 | song.play
155 | end
156 |
157 | kind = case year
158 | when 1850..1889 then 'Blues'
159 | when 1890..1909 then 'Ragtime'
160 | when 1910..1929 then 'New Orleans Jazz'
161 | when 1930..1939 then 'Swing'
162 | when 1940..1950 then 'Bebop'
163 | else 'Jazz'
164 | end
165 | ```
166 |
167 | * Passez des lignes entre les `def` pour diviser la méthode en paragraphes
168 | logiques.
169 |
170 | ```Ruby
171 | def some_method
172 | data = initialize(options)
173 |
174 | data.manipulate!
175 |
176 | data.result
177 | end
178 |
179 | def some_method
180 | result
181 | end
182 | ```
183 |
184 | * Alignez les paramètres de l'appel de méthode s'ils s'étalent sur plus d'une ligne.
185 |
186 | ```Ruby
187 | # point de départ (ligne trop longue)
188 | def send_mail(source)
189 | Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
190 | end
191 |
192 | # mauvais (indentation normale)
193 | def send_mail(source)
194 | Mailer.deliver(
195 | to: 'bob@example.com',
196 | from: 'us@example.com',
197 | subject: 'Important message',
198 | body: source.text)
199 | end
200 |
201 | # mauvais (double indentation)
202 | def send_mail(source)
203 | Mailer.deliver(
204 | to: 'bob@example.com',
205 | from: 'us@example.com',
206 | subject: 'Important message',
207 | body: source.text)
208 | end
209 |
210 | # bien
211 | def send_mail(source)
212 | Mailer.deliver(to: 'bob@example.com',
213 | from: 'us@example.com',
214 | subject: 'Important message',
215 | body: source.text)
216 | end
217 | ```
218 |
219 | * Ajoutez des tirets bas aux grands expressions numériques pour améliorer leur lisibilité.
220 |
221 | ```Ruby
222 | # mauvais - combien y a-t-il de zéros?
223 | num = 1000000
224 |
225 | # bien - bien plus simple à analyser pour le cerveau humain
226 | num = 1_000_000
227 | ```
228 |
229 | * Utilisez RDoc et ses conventions pour la documentation d'API. Ne
230 | passez pas de ligne entre le bloc de commentaire et le `def`.
231 | * Limitez les lignes à 80 caractères.
232 | * Evitez de laisser des espaces en fin de ligne.
233 |
234 | ## Syntaxe
235 |
236 | * Utilisez `def` avec des parenthèses quand il y a des arguments.
237 | Omettez les parenthèses quand la méthode n'accepte pas d'argument.
238 |
239 | ```Ruby
240 | def some_method
241 | # body omitted
242 | end
243 |
244 | def some_method_with_arguments(arg1, arg2)
245 | # body omitted
246 | end
247 | ```
248 |
249 | * N'utilisez jamais `for`, sauf si vous savez exactement pourquoi. En général,
250 | il vaut mieux utiliser les itérateurs. `for` est implémenté à la suite de `each`,
251 | mais avec une différence - `for` n'a pas de contexte propre (contrairement à `each`)
252 | et les variables définies dans son bloc seront visibles en dehors.
253 |
254 | ```Ruby
255 | arr = [1, 2, 3]
256 |
257 | # mauvais
258 | for elem in arr do
259 | puts elem
260 | end
261 |
262 | # bien
263 | arr.each { |elem| puts elem }
264 | ```
265 |
266 | * N'utilisez jamais `then` pour les `if/unless` sur plusieurs lignes.
267 |
268 | ```Ruby
269 | # mauvais
270 | if some_condition then
271 | # body omitted
272 | end
273 |
274 | # bien
275 | if some_condition
276 | # body omitted
277 | end
278 | ```
279 |
280 | * Privilégiez l'opérateur ternaire (`?:`) plutôt que des structures `if/then/else/end`.
281 | C'est plus courant et visiblement plus compact.
282 |
283 | ```Ruby
284 | # mauvais
285 | result = if some_condition then something else something_else end
286 |
287 | # bien
288 | result = some_condition ? something : something_else
289 | ```
290 |
291 | * Utilisez une seule expression par section dans un opérateur ternaire.
292 | Autrement dit, les opérateurs ternaires ne doivent pas être
293 | imbriqués. Privilégiez les structures `if/else` le cas échéant.
294 |
295 | ```Ruby
296 | # mauvais
297 | some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
298 |
299 | # bien
300 | if some_condition
301 | nested_condition ? nested_something : nested_something_else
302 | else
303 | something_else
304 | end
305 | ```
306 |
307 | * N'utilisez jamais `if x: ...` - cette syntaxe est supprimée en Ruby 1.9.
308 | Utilisez l'opérateur ternaire à la place.
309 |
310 | ```Ruby
311 | # mauvais
312 | result = if some_condition: something else something_else end
313 |
314 | # bien
315 | result = some_condition ? something : something_else
316 | ```
317 |
318 | * N'utilisez jamais `if x; ...`. Utilisez l'opérateur ternaire à la place.
319 |
320 | * Utilisez `when x then ...` pour les `case` sur une seule ligne.
321 | La syntaxe alternative `when x: ...` est supprimée en Ruby 1.9.
322 |
323 | * N'utilisez jamais `when x; ...`. Voir règle précédente.
324 |
325 | * Utilisez `&&/||` pour les expressions booléennes, `and/or` pour le flux de contrôle.
326 | (Règle d'or: Si vous devez mettre des parenthèses exterieures, vous utilisez les
327 | mauvais opérateurs.)
328 |
329 | ```Ruby
330 | # expression booléenne
331 | if some_condition && some_other_condition
332 | do_something
333 | end
334 |
335 | # flux de contrôle
336 | document.saved? or document.save!
337 | ```
338 |
339 | * Evitez les `?:` sur plusieurs lignes (opérateur ternaire); utilisez `if/unless` à la place.
340 |
341 | * Privilégiez l'utilisation des modificateurs `if/unless` pour les structures sur simple ligne.
342 | L'utilisation du contrôle de flux `and/or` est une alternative acceptable.
343 |
344 | ```Ruby
345 | # mauvais
346 | if some_condition
347 | do_something
348 | end
349 |
350 | # bien
351 | do_something if some_condition
352 |
353 | # alternative acceptable
354 | some_condition and do_something
355 | ```
356 |
357 | * Privilégiez `unless` plutôt que `if` pour les conditions négatives
358 | (ou le contrôle de flux `or`).
359 |
360 | ```Ruby
361 | # mauvais
362 | do_something if !some_condition
363 |
364 | # bien
365 | do_something unless some_condition
366 |
367 | # alternative acceptable
368 | some_condition or do_something
369 | ```
370 |
371 | * N'utilisez jamais `unless` avec `else`. Réécrivez ces structures
372 | avec le cas positif en premier.
373 |
374 | ```Ruby
375 | # mauvais
376 | unless success?
377 | puts 'failure'
378 | else
379 | puts 'success'
380 | end
381 |
382 | # bien
383 | if success?
384 | puts 'success'
385 | else
386 | puts 'failure'
387 | end
388 | ```
389 |
390 | * N'utilisez pas de parenthèses autour d'une condition `if/unless/while`,
391 | sauf si la condition contient une affectation (voir "Utilisation de la
392 | valeur de retour de `=`" ci-dessous).
393 |
394 | ```Ruby
395 | # mauvais
396 | if (x > 10)
397 | # contenu omis
398 | end
399 |
400 | # bien
401 | if x > 10
402 | # contenu omis
403 | end
404 |
405 | # acceptable
406 | if (x = self.next_value)
407 | # contenu omis
408 | end
409 | ```
410 |
411 | * Privilégiez l'utilisation d'un modificateur `while/until` pour les structures
412 | à simple ligne.
413 |
414 | ```Ruby
415 | # mauvais
416 | while some_condition
417 | do_something
418 | end
419 |
420 | # bien
421 | do_something while some_condition
422 | ```
423 |
424 | * Privilégiez `until` plutôt que `while` pour les conditions négatives.
425 |
426 | ```Ruby
427 | # mauvais
428 | do_something while !some_condition
429 |
430 | # bien
431 | do_something until some_condition
432 | ```
433 |
434 | * Omettez les parenthèses pour les méthodes qui font partie d'un DSL
435 | (Domain Specific Langage - ex: Rake, Rails, RSpec), qui ont un statut
436 | de "mot clé" en Ruby (ex: `attr_reader`, `puts`) et les méthodes d'accès
437 | à des attributs. Utilisez les parenthèses autour des arguments de toutes
438 | les autres invocations de méthodes.
439 |
440 | ```Ruby
441 | class Person
442 | attr_reader :name, :age
443 |
444 | # omis
445 | end
446 |
447 | temperance = Person.new('Temperance', 30)
448 | temperance.name
449 |
450 | puts temperance.age
451 |
452 | x = Math.sin(y)
453 | array.delete(e)
454 | ```
455 |
456 | * Privilégiez `{...}` plutôt que `do...end` pour les blocs sur simple ligne.
457 | Evitez l'utilisation de `{...}` pour les blocs multi-lignes (les enchainements
458 | multi-lignes sont toujours moches). Utilisez toujours `do...end` pour le
459 | "flux de contrôle" et les "définitions de méthodes" (ex: dans les Rakefiles
460 | et certains DSLs). Evitez les `do...end` dans les enchainements.
461 |
462 | ```Ruby
463 | names = ['Bozhidar', 'Steve', 'Sarah']
464 |
465 | # bien
466 | names.each { |name| puts name }
467 |
468 | # mauvais
469 | names.each do |name|
470 | puts name
471 | end
472 |
473 | # bien
474 | names.select { |name| name.start_with?('S') }.map { |name| name.upcase }
475 |
476 | # mauvais
477 | names.select do |name|
478 | name.start_with?('S')
479 | end.map { |name| name.upcase }
480 | ```
481 |
482 | Certains prétendront que les enchainements multi-lignes ont une bonne apparence en utilisant {...},
483 | mais ils devraient se demander - est-ce que ce code est vraiment lisible et est-ce que le contenu
484 | des blocs peut être extrait dans des méthodes efficaces?
485 |
486 | * Evitez `return` quand il n'est pas nécessaire pour le flux de contrôle.
487 |
488 | ```Ruby
489 | # mauvais
490 | def some_method(some_arr)
491 | return some_arr.size
492 | end
493 |
494 | # bien
495 | def some_method(some_arr)
496 | some_arr.size
497 | end
498 | ```
499 |
500 | * Evitez `self` quand il n'est pas nécessaire. (C'est nécessaire uniquement pour appeller un accesseur d'écriture local.)
501 |
502 | ```Ruby
503 | # mauvais
504 | def ready?
505 | if self.last_reviewed_at > self.last_updated_at
506 | self.worker.update(self.content, self.options)
507 | self.status = :in_progress
508 | end
509 | self.status == :verified
510 | end
511 |
512 | # bien
513 | def ready?
514 | if last_reviewed_at > last_updated_at
515 | worker.update(content, options)
516 | self.status = :in_progress
517 | end
518 | status == :verified
519 | end
520 | ```
521 |
522 | * En conséquence, évitez les ambiguïtés avec des variables locales, sauf si elles sont équivalentes.
523 |
524 | ```Ruby
525 | class Foo
526 | attr_accessor :options
527 |
528 | # acceptable
529 | def initialize(options)
530 | self.options = options
531 | # options et self.options sont ici équivalentes
532 | end
533 |
534 | # mauvais
535 | def do_something(options = {})
536 | unless options[:when] == :later
537 | output(self.options[:message])
538 | end
539 | end
540 |
541 | # bien
542 | def do_something(params = {})
543 | unless params[:when] == :later
544 | output(options[:message])
545 | end
546 | end
547 | end
548 | ```
549 |
550 | * Utilisez des espaces autour de l'opérateur `=` lors de l'assignation de valeurs par
551 | défaut à des paramètres de méthode:
552 |
553 | ```Ruby
554 | # mauvais
555 | def some_method(arg1=:default, arg2=nil, arg3=[])
556 | # do something...
557 | end
558 |
559 | # bien
560 | def some_method(arg1 = :default, arg2 = nil, arg3 = [])
561 | # do something...
562 | end
563 | ```
564 |
565 | Bien que beaucoup de livres Ruby conseillent le premier style, le second est
566 | bien plus fréquent (et probablement un peu plus lisible).
567 |
568 | * Evitez les prolongements de lignes (\\) quand ils ne sont pas indispensables.
569 | En pratique, évitez les prolongements de ligne tout court.
570 |
571 | ```Ruby
572 | # mauvais
573 | result = 1 - \
574 | 2
575 |
576 | # bien (mais toujours extrêmement moche)
577 | result = 1 \
578 | - 2
579 | ```
580 |
581 | * Utiliser la valeur de retour d'un `=` (une affectation) est acceptable,
582 | mais entourez l'assignement de parenthèses.
583 |
584 | ```Ruby
585 | # bien - montre l'utilisation prévue de l'affectation
586 | if (v = array.grep(/foo/)) ...
587 |
588 | # mauvais
589 | if v = array.grep(/foo/) ...
590 |
591 | # bien également - montre l'utilisation prévue de l'affectation et la priorité est correcte.
592 | if (v = self.next_value) == 'hello' ...
593 | ```
594 |
595 | * Utilisez `||=` à vonlonté pour initialiser les variables.
596 |
597 | ```Ruby
598 | # définit Bozhidar comme nom, seulement s'il vaut nil ou false
599 | name ||= 'Bozhidar'
600 | ```
601 |
602 | * N'utilisez pas `||=` pour initialiser des variables booléennes. (Imaginez ce
603 | qu'il se passerait si la valeur actuelle était `false`.)
604 |
605 | ```Ruby
606 | # mauvais - définirait enabled à true, même si elle valait false
607 | enabled ||= true
608 |
609 | # bien
610 | enabled = true if enabled.nil?
611 | ```
612 |
613 | * Evitez d'utiliser des variables spéciales de type Perl (comme
614 | `$0-9`, `$``, etc. ). Elles sont incompréhensibles et toute utilisation dans un
615 | script de plus d'une ligne est vivement déconseillée.
616 |
617 | * Ne mettez jamais d'espace entre le nom d'une méthode et la parenthèse d'ouverture.
618 |
619 | ```Ruby
620 | # mauvais
621 | f (3 + 2) + 1
622 |
623 | # bien
624 | f(3 + 2) + 1
625 | ```
626 |
627 | * Si le premier argument d'une méthode commence par une parenthèse ouvrante,
628 | utilisez toujours des parenthèses pour l'invocation de méthode. Ecrivez
629 | par exemple `f((3 + 2) + 1)`.
630 |
631 | * Lancez toujours l'interpréteur ruby avec l'option `-w` pour qu'il vous avertisse
632 | si vous avez oublié l'une des règles ci-dessus!
633 |
634 | * La nouvelle notation hash est à privilégier en Ruby 1.9 quand les clés de hash sont des symboles.
635 |
636 | ```Ruby
637 | # mauvais
638 | hash = { :one => 1, :two => 2 }
639 |
640 | # bien
641 | hash = { one: 1, two: 2 }
642 | ```
643 |
644 | * La nouvelle syntaxe lambda est à privilégier en Ruby 1.9.
645 |
646 | ```Ruby
647 | # mauais
648 | lambda = lambda { |a, b| a + b }
649 | lambda.call(1, 2)
650 |
651 | # bien
652 | lambda = ->(a, b) { a + b }
653 | lambda.(1, 2)
654 | ```
655 |
656 | * Utilisez `_` pour les paramètres de bloc inutilisés.
657 |
658 | ```Ruby
659 | # mauvais
660 | result = hash.map { |k, v| v + 1 }
661 |
662 | # bien
663 | result = hash.map { |_, v| v + 1 }
664 | ```
665 |
666 | ## Nommage
667 |
668 | > Les seules vraies difficultés en programmation sont l'invalidation de cache
669 | > et nommer les choses.
670 | > -- Phil Karlton
671 |
672 | * Utilisez le `snake_case` pour les méthodes et les variables.
673 | * Utilisez le `CamelCase` pour les classes et les modules. (Gardez les acronymes comme HTTP,
674 | RFC, XML en majuscules.)
675 | * Utilisez le `SCREAMING_SNAKE_CASE` pour les autres constantes.
676 | * Le nom des méthodes qui retournent obligatoirement une valeur booléenne doit
677 | finir par un point d'interrogation.
678 | (ex: `Array#empty?`).
679 | * Le nom des méthodes potentiellement "dangereuses" (ex: les méthodes qui modifient `self` ou
680 | les arguments, `exit!` (qui n'exécute pas les finaliseurs contrairement à `exit`), etc.)
681 | devraient finir par un point d'exclamation (bang) s'il existe une version sécurisée de cette méthode
682 | *dangereuse*.
683 |
684 | ```Ruby
685 | # mauvais - il n'y a pas de méthode 'sécurisée'
686 | class Person
687 | def update!
688 | end
689 | end
690 |
691 | # bien
692 | class Person
693 | def update
694 | end
695 | end
696 |
697 | # bien
698 | class Person
699 | def update!
700 | end
701 |
702 | def update
703 | end
704 | end
705 | ```
706 |
707 | * Définissez la méthode "non bang" (sécurisée) à la suite de la version "bang" (dangereuse)
708 | si possible.
709 |
710 | ```Ruby
711 | class Array
712 | def flatten_once!
713 | res = []
714 |
715 | each do |e|
716 | [*e].each { |f| res << f }
717 | end
718 |
719 | replace(res)
720 | end
721 |
722 | def flatten_once
723 | dup.flatten_once!
724 | end
725 | end
726 | ```
727 |
728 | * Lorsque vous utilisez `reduce` avec un bloc court, nommez les arguments `|a, e|`
729 | (accumulator, element).
730 | * Lorsque vous définissez des opérateurs binaires, nommez l'argument `other`.
731 |
732 | ```Ruby
733 | def +(other)
734 | # contenu omis
735 | end
736 | ```
737 |
738 | * Privilégiez `map` plutôt que `collect`, `find` plutôt que `detect`,
739 | `select` plutôt que `find_all`, `reduce` plutôt que `inject` et
740 | `size` plutôt que `length`. Ce n'est pas une exigence absolue;
741 | si l'utilisation de l'alias améliore la lisibilité, il est acceptable
742 | de l'utiliser. Les methodes qui riment sont un héritage de Smalltalk
743 | et ne sont pas courantes dans les autres langages de programmation.
744 | La raison pour laquelle l'utilisation de `select` est encouragée plutôt
745 | que `find_all` est qu'elle fonctionne bien avec `reject` et que son nom est
746 | relativement explicite.
747 |
748 | * Utilisez `flat_map` plutôt que `map` + `flatten`.
749 |
750 | ```Ruby
751 | # mauvais
752 | all_songs = users.map(&:songs).flatten.uniq
753 |
754 | # bien
755 | all_songs = users.flat_map(&:songs).uniq
756 | ```
757 |
758 | ## Commentaires
759 |
760 | > Un code de qualité constitue sa propre documentation. Quand vous êtes
761 | > sur le point d'ajouter un commentaire, demandez-vous, "Comment puis-je
762 | > améliorer le code pour que ce commentaire ne soit pas nécessaire?"
763 | > Améliorez le code et documentez le ensuite pour le rendre encore plus limpide.
764 | > -- Steve McConnell
765 |
766 | * Ecrivez du code auto-documenté et ignorez le reste de cette section. Vraiment!
767 | * Les commentaires doivent toujours être écrits en anglais pour éviter les problèmes
768 | liés aux caractères spéciaux.
769 | * La capitalisation et la ponctuation doivent être appliquées aux commentaires
770 | de plus d'un mot. Utilisez [un espace](http://monsu.desiderio.free.fr/atelier/espace.html) après les virgules.
771 | * Evitez les comemntaires superflus.
772 |
773 | ```Ruby
774 | # mauvais
775 | counter += 1 # incrémente le compteur de 1
776 | ```
777 |
778 | * Tenez à jour les commentaires existants. Un commentaire obsolète est pire que pas
779 | de commentaire du tout.
780 |
781 | > Un bon code est comme une bonne blague - il n'a pas besoin d'explication.
782 | > -- Russ Olsen
783 |
784 | * Evitez d'écrire des commentaires pour expliquer un mauvais code.
785 | Refactorisez ce code pour le rendre explicite.(Fais-le, ou ne le fais pas, mais il n'y a pas d'essai. --Yoda)
786 |
787 | ### Commentaires d'annotation
788 |
789 | * Les annotations devraient généralement être écrites à la ligne juste
790 | au dessus du code concerné.
791 | * Les mots-clés d'annotation sont suivis par deux points et un espace,
792 | suivis d'une note décrivant le problème.
793 | * Si plusieurs lignes sont nécessaires pour décrire le problème, les
794 | lignes suivantes doivent être indentées de deux espaces après le `#`.
795 |
796 | ```Ruby
797 | def bar
798 | # FIXME: This has crashed occasionally since v3.2.1. It may
799 | # be related to the BarBazUtil upgrade.
800 | baz(:quux)
801 | end
802 | ```
803 |
804 | * Si le problème est tellement évident que toute documentation serait
805 | redondante, les annotations peuvent être laissées à la fin de la ligne
806 | concernée sans description. Cet usage doit être l'exception et non la règle.
807 |
808 | ```Ruby
809 | def bar
810 | sleep 100 # OPTIMIZE
811 | end
812 | ```
813 |
814 | * Utilisez `TODO` pour marquer les fonctionnalités manquantes ou qui devraient
815 | être ajoutées ultérieurement.
816 | * Utilisez `FIXME` pour signaler un code erroné qui doit être corrigé.
817 | * Utilisez `OPTIMIZE` pour signaler un code lent ou inefficace pouvant poser
818 | des problèmes de performance.
819 | * Utilisez `HACK` pour signaler un code qui semble être issu de pratiques
820 | d'écriture douteuses qui devrait être refactorisé.
821 | * Utilisez `REVIEW` pour signaler toute chose devant être vérifiée pour confirmer
822 | qu'elle fonctionne comme prévu. Par exemple: `REVIEW: Are we sure this is how the
823 | client does X currently?`
824 | * Utilisez d'autres mots clés d'annotation personnalisés si vous considérez que c'est
825 | approprié, mais assurez-vous de les documenter dans le `README` de votre projet.
826 |
827 | ## Classes
828 |
829 | * Quand vous concevez des hiérarchies de classes, assurez-vous qu'elles sont conformes au
830 | [Principe de substitution de Liskov](http://fr.wikipedia.org/wiki/Principe_de_substitution_de_Liskov).
831 | * Essayez de rendre vos classes aussi
832 | SOLIDES
833 | que possible.
834 | * Fournissez toujours une méthode `to_s` appropriée aux classes qui
835 | représentent des objets de domaine.
836 |
837 | ```Ruby
838 | class Person
839 | attr_reader :first_name, :last_name
840 |
841 | def initialize(first_name, last_name)
842 | @first_name = first_name
843 | @last_name = last_name
844 | end
845 |
846 | def to_s
847 | "#@first_name #@last_name"
848 | end
849 | end
850 | ```
851 |
852 | * Utilisez la famille de fonctions `attr` pour définir des accesseurs
853 | de lecture ou d'écriture.
854 |
855 | ```Ruby
856 | # mauvais
857 | class Person
858 | def initialize(first_name, last_name)
859 | @first_name = first_name
860 | @last_name = last_name
861 | end
862 |
863 | def first_name
864 | @first_name
865 | end
866 |
867 | def last_name
868 | @last_name
869 | end
870 | end
871 |
872 | # bien
873 | class Person
874 | attr_reader :first_name, :last_name
875 |
876 | def initialize(first_name, last_name)
877 | @first_name = first_name
878 | @last_name = last_name
879 | end
880 | end
881 | ```
882 |
883 | * Pensez à utiliser `Struct.new`, qui définit les accesseurs triviaux,
884 | constructeurs et operateurs de comparaison pour vous.
885 |
886 | ```Ruby
887 | # bien
888 | class Person
889 | attr_reader :first_name, :last_name
890 |
891 | def initialize(first_name, last_name)
892 | @first_name = first_name
893 | @last_name = last_name
894 | end
895 | end
896 |
897 | # meilleur
898 | class Person < Struct.new(:first_name, :last_name)
899 | end
900 | ````
901 |
902 | * Pensez à ajouter des méthodes de fabrique pour faciliter la création
903 | d'instances d'une classe donnée.
904 |
905 | ```Ruby
906 | class Person
907 | def self.create(options_hash)
908 | # contenu omis
909 | end
910 | end
911 | ```
912 |
913 | * Privilégiez le [duck-typing](http://fr.wikipedia.org/wiki/Duck_typing) plutôt que l'héritage.
914 |
915 | ```Ruby
916 | # mauvais
917 | class Animal
918 | # méthode abstraite
919 | def speak
920 | end
921 | end
922 |
923 | # extension de la superclass
924 | class Duck < Animal
925 | def speak
926 | puts 'Quack! Quack'
927 | end
928 | end
929 |
930 | # extension de la superclass
931 | class Dog < Animal
932 | def speak
933 | puts 'Bau! Bau!'
934 | end
935 | end
936 |
937 | # bien
938 | class Duck
939 | def speak
940 | puts 'Quack! Quack'
941 | end
942 | end
943 |
944 | class Dog
945 | def speak
946 | puts 'Bau! Bau!'
947 | end
948 | end
949 | ```
950 |
951 | * Evitez l'utilisation des variables de classe (`@@`) à cause de leur comportement
952 | pénible avec l'héritage.
953 |
954 | ```Ruby
955 | class Parent
956 | @@class_var = 'parent'
957 |
958 | def self.print_class_var
959 | puts @@class_var
960 | end
961 | end
962 |
963 | class Child < Parent
964 | @@class_var = 'child'
965 | end
966 |
967 | Parent.print_class_var # => va écrire "child"
968 | ```
969 |
970 | Comme vous pouvez le voir, toutes les classes de la hiérarchie partagent
971 | en fait la même variable de classe. Les variables d'instance de classe
972 | devraient généralement être privilégiées à la place des variables de classe.
973 |
974 | * Affectez aux méthodes les niveaux de visibilité (`private`, `protected`) appropriés
975 | conformément à leur utilisation attendue. Ne laissez pas tout en `public`
976 | (par défaut). Après tout, nous codons en *Ruby* là, pas en *Python*.
977 | * Indentez les méthodes `public`, `protected`, et `private` au même niveau que les
978 | définitions de methodes auxquelles elles s'appliquent. Passez une ligne au dessus
979 | du modificateur de visibilité et une ligne en dessous de façon à accentuer le fait
980 | qu'il s'applique à toutes les méthodes qui le suivent.
981 |
982 | ```Ruby
983 | class SomeClass
984 | def public_method
985 | # ...
986 | end
987 |
988 | private
989 |
990 | def private_method
991 | # ...
992 | end
993 |
994 | def another_private_method
995 | # ...
996 | end
997 | end
998 | ```
999 |
1000 | * Utilisez `def self.method` pour définir les méthodes singleton. Cela rend le code plus
1001 | facile à refactoriser car le nom de la classe n'est pas répété.
1002 |
1003 | ```Ruby
1004 | class TestClass
1005 | # mauvais
1006 | def TestClass.some_method
1007 | # contenu omis
1008 | end
1009 |
1010 | # bien
1011 | def self.some_other_method
1012 | # contenu omis
1013 | end
1014 |
1015 | # Egalement possible et pratique quand vous
1016 | # devez définir plusieurs méthodes singleton.
1017 | class << self
1018 | def first_method
1019 | # contenu omis
1020 | end
1021 |
1022 | def second_method_etc
1023 | # contenu omis
1024 | end
1025 | end
1026 | end
1027 | ```
1028 |
1029 | ## Exceptions
1030 |
1031 | * Signalez les exceptions en utilisant la méthode `fail`. Utilisez
1032 | `raise` uniquement lorsque vous capturez une exception et la levez
1033 | à nouveau (parcequ'il ne s'agit pas d'un échec mais d'une levée
1034 | d'exception explicite et intentionnelle).
1035 |
1036 | ```Ruby
1037 | begin
1038 | fail 'Oops';
1039 | rescue => error
1040 | raise if error.message != 'Oops'
1041 | end
1042 | ```
1043 |
1044 | * Ne jamais utiliser `return` dans un bloc `ensure`. Cela donnerait
1045 | la priorité au retour sur une éventuelle levée d'exception,
1046 | et la méthode retournerait un résultat comme si aucune exception
1047 | n'avait été levée. En fait, l'exception serait ignorée silencieusement.
1048 |
1049 | ```Ruby
1050 | def foo
1051 | begin
1052 | fail
1053 | ensure
1054 | return 'very bad idea'
1055 | end
1056 | end
1057 | ```
1058 |
1059 | * Utilisez des blocs `begin` implicites autant que possible.
1060 |
1061 | ```Ruby
1062 | # mauvais
1063 | def foo
1064 | begin
1065 | # algorithme principal
1066 | rescue
1067 | # gestion d'échec
1068 | end
1069 | end
1070 |
1071 | # bien
1072 | def foo
1073 | # algorithme principal
1074 | rescue
1075 | # gestion d'échec
1076 | end
1077 | ```
1078 |
1079 | * Limitez la prolifération des blocs `begin` en utilisant
1080 | les *méthodes de contingence* (un terme inventé par Avdi Grimm.)
1081 |
1082 | ```Ruby
1083 | # mauvais
1084 | begin
1085 | something_that_might_fail
1086 | rescue IOError
1087 | # handle IOError
1088 | end
1089 |
1090 | begin
1091 | something_else_that_might_fail
1092 | rescue IOError
1093 | # handle IOError
1094 | end
1095 |
1096 | # bien
1097 | def with_io_error_handling
1098 | yield
1099 | rescue IOError
1100 | # handle IOError
1101 | end
1102 |
1103 | with_io_error_handling { something_that_might_fail }
1104 |
1105 | with_io_error_handling { something_else_that_might_fail }
1106 | ```
1107 |
1108 | * Ne supprimez pas les exceptions.
1109 |
1110 | ```Ruby
1111 | # mauvais
1112 | begin
1113 | # une exception se produit ici
1114 | rescue SomeError
1115 | # la section de secours ne fait absolument rien
1116 | end
1117 |
1118 | # mauvais
1119 | do_something rescue nil
1120 | ```
1121 |
1122 | * Evitez l'utilisation de `rescue` sous sa forme de modificateur.
1123 |
1124 | ```Ruby
1125 | # mauvais - cela capture toutes les exceptions StandardError
1126 | do_something rescue nil
1127 | ```
1128 |
1129 | * N'utilisez pas d'exception pour le flux de contrôle.
1130 |
1131 | ```Ruby
1132 | # mauvais
1133 | begin
1134 | n / d
1135 | rescue ZeroDivisionError
1136 | puts 'Cannot divide by 0!'
1137 | end
1138 |
1139 | # bien
1140 | if d.zero?
1141 | puts 'Cannot divide by 0!'
1142 | else
1143 | n / d
1144 | end
1145 | ```
1146 |
1147 | * Evitez `rescue Exception`. Cela aurait pour effet d'intercepter les
1148 | signaux et appels à `exit`, et nécesiterait de `kill -9` le processus.
1149 |
1150 | ```Ruby
1151 | # mauvais
1152 | begin
1153 | # les appels de signaux exit et kill sont interceptés (sauf kill -9).
1154 | exit
1155 | rescue Exception
1156 | puts "vous ne vouliez pas vraiment arrêter, pas vrai?"
1157 | # gestion d'exception
1158 | end
1159 |
1160 | # bien
1161 | begin
1162 | # un rescue par défaut intercepte les exceptions StandardError et non Exception,
1163 | # contrairement à ce que pensent beaucoup de développeurs.
1164 | rescue => e
1165 | # gestion d'exception
1166 | end
1167 |
1168 | # bien aussi
1169 | begin
1170 | # une exception se produit ici
1171 |
1172 | rescue StandardError => e
1173 | # gestion d'exception
1174 | end
1175 |
1176 | ```
1177 |
1178 | * Placez les exceptions spécifiques en haut de la chaine d'interception,
1179 | sans quoi elle ne seront jamais interceptées.
1180 |
1181 | ```Ruby
1182 | # mauvais
1183 | begin
1184 | # du code
1185 | rescue Exception => e
1186 | # gestion d'exception
1187 | rescue StandardError => e
1188 | # gestion d'exception
1189 | end
1190 |
1191 | # bien
1192 | begin
1193 | # du code
1194 | rescue StandardError => e
1195 | # gestion d'exception
1196 | rescue Exception => e
1197 | # gestion d'exception
1198 | end
1199 | ```
1200 |
1201 | * Libérez les ressources externes ouvertes par votre programme
1202 | dans un bloc `ensure`.
1203 |
1204 | ```Ruby
1205 | f = File.open('testfile')
1206 | begin
1207 | # .. processus
1208 | rescue
1209 | # .. gestion d'erreur
1210 | ensure
1211 | f.close unless f.nil?
1212 | end
1213 | ```
1214 |
1215 | * Privilégiez l'utilisation d'exceptions standards plutôt que
1216 | d'introduire de nouvelles classes d'exception.
1217 |
1218 | ## Collections
1219 |
1220 | * Privilégiez la notation littérale pour créer des tableaux ou des hashs.
1221 | (sauf si vous devez passer des paramètres à leurs constructeurs).
1222 |
1223 | ```Ruby
1224 | # mauvais
1225 | arr = Array.new
1226 | hash = Hash.new
1227 |
1228 | # bien
1229 | arr = []
1230 | hash = {}
1231 | ```
1232 |
1233 | * Privilégiez `%w` à la syntaxe littérale de création de tableau
1234 | quand vous avez besoin d'un tableau de chaines de caractères.
1235 |
1236 | ```Ruby
1237 | # mauvais
1238 | STATES = ['draft', 'open', 'closed']
1239 |
1240 | # bien
1241 | STATES = %w(draft open closed)
1242 | ```
1243 |
1244 | * Evitez de créer des écarts énormes dans les tableaux.
1245 |
1246 | ```Ruby
1247 | arr = []
1248 | arr[100] = 1 # là vous avez un tableau avec plein de nil.
1249 | ```
1250 |
1251 | * Utilisez `Set` plutôt que `Array` pour traiter des éléments uniques.
1252 | `Set` gère une liste de valeurs non ordonnées sans doublons.
1253 | C'est un croisement entre les capacités interopérables et intuitives
1254 | de `Array` et la recherche rapide de `Hash`.
1255 | * Privilégiez les symboles plutôt que les chaines de caractères pour
1256 | les clés de hash.
1257 |
1258 | ```Ruby
1259 | # mauvais
1260 | hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
1261 |
1262 | # bien
1263 | hash = { one: 1, two: 2, three: 3 }
1264 | ```
1265 |
1266 | * Evitez d'utiliser des objets modifiables comme clés de hash.
1267 | * Privilégiez la nouvelle notation hash en Ruby 1.9 lorsque vos clés sont des symboles.
1268 |
1269 | ```Ruby
1270 | # mauvais
1271 | hash = { :one => 1, :two => 2, :three => 3 }
1272 |
1273 | # bien
1274 | hash = { one: 1, two: 2, three: 3 }
1275 | ```
1276 |
1277 | * Utilisez `fetch` pour manipuler des clés de hash qui sont
1278 | censées être présentes.
1279 |
1280 | ```Ruby
1281 | heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
1282 | # mauvais - une erreur pourrait ne pas être remarquée
1283 | heroes[:batman] # => "Bruce Wayne"
1284 | heroes[:supermann] # => nil
1285 |
1286 | # bien - fetch génère une exception KeyError, rendant le problème évident
1287 | heroes.fetch(:supermann)
1288 | ```
1289 |
1290 | * Basez-vous sur le fait que les hash en Ruby 1.9 sont ordonnés.
1291 | * Ne jamais modifier une collection en la parcourant.
1292 |
1293 | ## Chaînes de caractères
1294 |
1295 | * Privilégiez l'interpolation de chaîne plutôt que la concaténation:
1296 |
1297 | ```Ruby
1298 | # mauvais
1299 | email_with_name = user.name + ' <' + user.email + '>'
1300 |
1301 | # bien
1302 | email_with_name = "#{user.name} <#{user.email}>"
1303 | ```
1304 |
1305 | * Pensez à entourer le code interpolé d'un espace. Cela permet de mieux
1306 | distinguer le code de la chaîne de caractères.
1307 |
1308 | ```Ruby
1309 | "#{ user.last_name }, #{ user.first_name }"
1310 | ```
1311 |
1312 | * Privilégiez les chaîne à guillemets simples lorsque vous n'utilisez pas
1313 | d'interpolation ou de caractères spéciaux comme `\t`, `\n`, `'`, etc.
1314 |
1315 | ```Ruby
1316 | # mauvais
1317 | name = "Bozhidar"
1318 |
1319 | # bien
1320 | name = 'Bozhidar'
1321 | ```
1322 |
1323 | * N'utilisez pas `{}` autour des variables d'instance interpolées dans
1324 | une chaîne.
1325 |
1326 | ```Ruby
1327 | class Person
1328 | attr_reader :first_name, :last_name
1329 |
1330 | def initialize(first_name, last_name)
1331 | @first_name = first_name
1332 | @last_name = last_name
1333 | end
1334 |
1335 | # mauvais
1336 | def to_s
1337 | "#{@first_name} #{@last_name}"
1338 | end
1339 |
1340 | # bien
1341 | def to_s
1342 | "#@first_name #@last_name"
1343 | end
1344 | end
1345 | ```
1346 |
1347 | * Evitez d'utiliser `String#+` pour assembler de longues chaînes de caractères.
1348 | Utilisez plutôt `String#<<` qui transforme la chaîne sur place et s'avère
1349 | toujours plus rapide que `String#+`, qui crée beaucoup de nouveaux objets.
1350 |
1351 | ```Ruby
1352 | # bien et rapide
1353 | html = ''
1354 | html << '
Page title
'
1355 |
1356 | paragraphs.each do |paragraph|
1357 | html << "#{paragraph}
"
1358 | end
1359 | ```
1360 |
1361 | ## Expressions rationnelles
1362 |
1363 | > Certaines personnes se disent, lorsqu'elles sont confrontées à un problème
1364 | > "Je sais, je vais utiliser les expressions rationnelles."
1365 | > Et elles se retrouvent avec deux problèmes.
1366 | > -- Jamie Zawinski
1367 |
1368 | * N'utilisez pas d'expression rationnelle pour une simple recherche de texte
1369 | en clair dans une chaîne de caractères: `string['text']`
1370 | * Pour des situations simples, vous pouvez utiliser la regexp directement
1371 | dans l'index de chaîne.
1372 |
1373 | ```Ruby
1374 | match = string[/regexp/] # récupère le contenu correspondant à la regexp
1375 | first_group = string[/text(grp)/, 1] # récupère le contenu du groupe capturé
1376 | string[/text (grp)/, 1] = 'replace' # string => 'text replace'
1377 | ```
1378 |
1379 | * Utiliser les groupes non capturants quand vous n'utilisez pas le résultat
1380 | capturé par les parenthèses.
1381 |
1382 | ```Ruby
1383 | /(first|second)/ # mauvais
1384 | /(?:first|second)/ # bien
1385 | ```
1386 |
1387 | * Evitez d'utiliser $1-9 car il peut être difficile de déterminer ce qu'ils
1388 | contiennent. Les groupes nommés peuvent être utilisés à la place.
1389 |
1390 | ```Ruby
1391 | # mauvais
1392 | /(regexp)/ =~ string
1393 | ...
1394 | process $1
1395 |
1396 | # bien
1397 | /(?regexp)/ =~ string
1398 | ...
1399 | process meaningful_var
1400 | ```
1401 |
1402 | * Les classes de caractères comportent juste quelques caractères spéciaux
1403 | dont vous devez vous soucier: `^`, `-`, `\`, `]`, alors n'échappez pas
1404 | `.` ou les crochets dans `[]`.
1405 |
1406 | * Faites attention avec `^` et `$` car ils correspondent aux débuts et
1407 | fins de lignes, pas de la chaîne.
1408 | Si vous cherchez une correspondance avec la chaîne entière, utilisez
1409 | `\A` et `\z` (à ne pas confondre avec `\Z` qui est l'équivalent de `/\n?\z/`).
1410 |
1411 | ```Ruby
1412 | string = "some injection\nusername"
1413 | string[/^username$/] # correspondance
1414 | string[/\Ausername\z/] # pas de correspondance
1415 | ```
1416 |
1417 | * Utilisez le modificateur `x` pour les regexps complexes. Cela les rend plus
1418 | lisibles et vous pouvez ajouter des commentaires utiles. Faites juste
1419 | attention aux espaces qui sont ignorés.
1420 |
1421 | ```Ruby
1422 | regexp = %r{
1423 | start # du texte
1424 | \s # un caractère d'espacement
1425 | (group) # premier groupe
1426 | (?:alt1|alt2) # une alternative
1427 | end
1428 | }x
1429 | ```
1430 |
1431 | * Pour des remplacements complexes, `sub`/`gsub` peuvent être utilisés
1432 | avec un bloc ou un hash.
1433 |
1434 | ## Notations pourcents
1435 |
1436 | * Utilisez `%w` à vonlonté.
1437 |
1438 | ```Ruby
1439 | STATES = %w(draft open closed)
1440 | ```
1441 |
1442 | * Utilisez `%()` pour les chaînes à simple ligne qui nécessitent à la fois
1443 | une interpolation et l'inclusion de doubles guillemets. Pour les chaînes
1444 | multi-lignes, privilégiez les heredocs.
1445 |
1446 | ```Ruby
1447 | # mauvais (pas besoin d'interpolation)
1448 | %(Some text
)
1449 | # devrait être 'Some text
'
1450 |
1451 | # mauvais (pas de double guillemet)
1452 | %(This is #{quality} style)
1453 | # should be "This is #{quality} style"
1454 |
1455 | # mauvais (multi-lignes)
1456 | %(\n#{exclamation}\n
)
1457 | # should be a heredoc.
1458 |
1459 | # bien (interpolation, doubles guillemets, simple ligne)
1460 | %(#{name} | )
1461 | ```
1462 |
1463 | * Utilisez `%r` uniquement pour les expressions régulières recherchant *plus d'un* caractère '/'.
1464 |
1465 | ```Ruby
1466 | # mauvais
1467 | %r(\s+)
1468 |
1469 | # encore mauvais
1470 | %r(^/(.*)$)
1471 | # should be /^\/(.*)$/
1472 |
1473 | # bien
1474 | %r(^/blog/2011/(.*)$)
1475 | ```
1476 |
1477 | * Evitez `%q`, `%Q`, `%x`, `%s`, and `%W`.
1478 |
1479 | * Privilégiez `()` comme délimiteurs pour toutes les notations `%`.
1480 |
1481 | ## Méta-programmation
1482 |
1483 | * Evitez la méta-programmation inutile.
1484 |
1485 | * Ne modifiez pas le comportement des classes du noyau lorsque vous écrivez des librairies.
1486 | (Ne leur appliquez pas de "monkey-patch")
1487 |
1488 | * La forme de bloc de `class_eval` est préférable à la form de chaîne interpolée.
1489 | - Quand vous utilisez une chaîne interpolée, fournissez toujours `__FILE__` et `__LINE__`,
1490 | de sorte que vos piles d'exécution aient du sens:
1491 |
1492 | ```ruby
1493 | class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__
1494 | ```
1495 |
1496 | - `define_method` est préférable à `class_eval{ def ... }`
1497 |
1498 | * Lorsque vous utilisez `class_eval` (ou tout autre `eval`) avec une chaîne interpolée,
1499 | ajoutez un bloc de commentaire montrant son apparence une fois interpolée (c'est une
1500 | pratique que j'ai apprise dans le code source de Rails):
1501 |
1502 | ```ruby
1503 | # from activesupport/lib/active_support/core_ext/string/output_safety.rb
1504 | UNSAFE_STRING_METHODS.each do |unsafe_method|
1505 | if 'String'.respond_to?(unsafe_method)
1506 | class_eval <<-EOT, __FILE__, __LINE__ + 1
1507 | def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
1508 | to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)
1509 | end # end
1510 |
1511 | def #{unsafe_method}!(*args) # def capitalize!(*args)
1512 | @dirty = true # @dirty = true
1513 | super # super
1514 | end # end
1515 | EOT
1516 | end
1517 | end
1518 | ```
1519 |
1520 | * Evitez d'utilisez `method_missing` pour la méta-programmation. Cela complexifie les piles
1521 | d'exécution; le comportement n'est pas listé dans `#methods`; les appels de méthodes mal
1522 | orthographiés pourraient fonctionner sans générer d'erreur (`nukes.launch_state = false`).
1523 | Pensez à utiliser la délégation, la procuration ou `define_method` à la place. Si vous devez
1524 | vraiment utiliser `method_missing`:
1525 | - [Définissez également `respond_to_missing?`](http://blog.marc-andre.ca/2010/11/methodmissing-politely.html)
1526 | - Interceptez seulement les méthodes comportant un préfixe bien défini, comme `find_by_*` -- rendez votre code aussi robuste que possible.
1527 | - Appelez `super` à la fin de votre traitement.
1528 | - Déléguez vers des méthodes robustes et non-magiques:
1529 |
1530 | ```ruby
1531 | # mauvais
1532 | def method_missing?(meth, *args, &block)
1533 | if /^find_by_(?.*)/ =~ meth
1534 | # ... beaucoup de code pour faire un find_by
1535 | else
1536 | super
1537 | end
1538 | end
1539 |
1540 | # bien
1541 | def method_missing?(meth, *args, &block)
1542 | if /^find_by_(?.*)/ =~ meth
1543 | find_by(prop, *args, &block)
1544 | else
1545 | super
1546 | end
1547 | end
1548 |
1549 | # La meilleure solution serait cependant d'utiliser define_method pour chaque attribut
1550 | # utilisable au travers de la méthode find_by.
1551 | ```
1552 |
1553 | ## Divers
1554 |
1555 | * Ecrivez du code ruby sécurisé grace à `ruby -w`.
1556 | * Evitez les hashs comme paramètres optionnels. La méthode n'en ferait-elle pas trop ?
1557 | * Evitez les méthodes de plus de 10 lignes de code (sans compter les lignes vides).
1558 | Idéalement, la plupart des méthodes devraient faire moins de 5 lignes.
1559 | * Evitez les listes de paramètres plus longues que trois ou quatre paramètres.
1560 | * Si vous avez vraiment besoin de méthodes "globales", ajoutez les au noyau
1561 | en tant que méthodes privées.
1562 | * Utilisez les variables d'instances de classe plutôt que des variables globales
1563 |
1564 | ```Ruby
1565 | # mauvais
1566 | $foo_bar = 1
1567 |
1568 | # bien
1569 | class Foo
1570 | class << self
1571 | attr_accessor :bar
1572 | end
1573 | end
1574 |
1575 | Foo.bar = 1
1576 | ```
1577 | * Evitez d'utiliser `alias` quand vous pouvez utiliser `alias_method`.
1578 | * Utilisez `OptionParser` pour analyser des options de ligne de commande
1579 | complexes et `ruby -s` pour des options de ligne de commande simples.
1580 | * Codez de manière fonctionnelle, en évitant la mutation autant que possible.
1581 | * Ne modifiez pas les arguments sauf si c'est l'objectif de la méthode.
1582 | * Evitez les imbrications de blocs sur plus de trois niveaux.
1583 | * Soyez cohérent. Dans un monde idéal, soyez cohérent avec ces lignes directrices.
1584 | * Utilisez votre bon sens.
1585 |
1586 | # Contribuer
1587 |
1588 | Rien de ce qui est écrit dans ce guide n'est gravé dans le marbre. Mon
1589 | but est que nous travaillions ensemble avec toutes les personnes intéressées
1590 | par le style de programmation Ruby, de telle sorte que nous puissions créer
1591 | une ressource qui serait bénéfique à l'ensemble de la communauté Ruby.
1592 |
1593 | N'hésitez pas à ouvrir des tickets ou d'envoyer des 'pull-requests' avec vos
1594 | améliorations. Merci d'avance pour votre aide!
1595 |
1596 | # Passez le mot
1597 |
1598 | Un guide piloté par la communauté n'apportera pas grand chose à une
1599 | communauté qui n'est pas au courant de son existence. Tweetez à propos
1600 | du guide, partagez le avec vos amis et collègues. Chaque commentaire,
1601 | chaque suggestion ou opinion que nous recevons rendra le guide encore
1602 | meilleur. Et ce que nous voulons, c'est avoir le meilleur guide possible,
1603 | n'est-ce pas?
1604 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Prelude
2 |
3 | > Style is what separates the good from the great.
4 | > -- Bozhidar Batsov
5 |
6 | One thing has always bothered me as Ruby developer - Python developers
7 | have a great programming style reference
8 | ([PEP-8](http://www.python.org/dev/peps/pep-0008/)) and we never got
9 | an official guide, documenting Ruby coding style and best
10 | practices. And I do believe that style matters. I also believe that
11 | such fine fellows, like us Ruby developers, should be quite capable to
12 | produce this coveted document.
13 |
14 | This guide started its life as our internal company Ruby coding guidelines
15 | (written by yours truly). At some point I decided that the work I was
16 | doing might be interesting to members of the Ruby community in general
17 | and that the world had little need for another internal company
18 | guideline. But the world could certainly benefit from a
19 | community-driven and community-sanctioned set of practices, idioms and
20 | style prescriptions for Ruby programming.
21 |
22 | Since the inception of the guide I've received a lot of feedback from
23 | members of the exceptional Ruby community around the world. Thanks for
24 | all the suggestions and the support! Together we can make a resource
25 | beneficial to each and every Ruby developer out there.
26 |
27 | By the way, if you're into Rails you might want to check out the
28 | complementary
29 | [Ruby on Rails 3 Style Guide](https://github.com/bbatsov/rails-style-guide).
30 |
31 | # The Ruby Style Guide
32 |
33 | This Ruby style guide recommends best practices so that real-world Ruby
34 | programmers can write code that can be maintained by other real-world Ruby
35 | programmers. A style guide that reflects real-world usage gets used, and a
36 | style guide that holds to an ideal that has been rejected by the people it is
37 | supposed to help risks not getting used at all – no matter how good it is.
38 |
39 | The guide is separated into several sections of related rules. I've
40 | tried to add the rationale behind the rules (if it's omitted I've
41 | assumed that is pretty obvious).
42 |
43 | I didn't come up with all the rules out of nowhere - they are mostly
44 | based on my extensive career as a professional software engineer,
45 | feedback and suggestions from members of the Ruby community and
46 | various highly regarded Ruby programming resources, such as
47 | ["Programming Ruby 1.9"](http://pragprog.com/book/ruby3/programming-ruby-1-9)
48 | and ["The Ruby Programming Language"](http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177).
49 |
50 | The guide is still a work in progress - some rules are lacking
51 | examples, some rules don't have examples that illustrate them clearly
52 | enough. In due time these issues will be addressed - just keep them in
53 | mind for now.
54 |
55 | You can generate a PDF or an HTML copy of this guide using
56 | [Transmuter](https://github.com/TechnoGate/transmuter).
57 |
58 | The [rubocop](https://github.com/bbatsov/rubocop) project aims to
59 | provide an automated way to check whether a Ruby code base complies
60 | with the style guide. Currently it's far from being production ready and it's missing
61 | lots of features. Everyone is naturally invited to help improve it!
62 |
63 | Translations of the guide are available in the following languages:
64 |
65 | * [Chinese Simplified](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhCN.md)
66 | * [Chinese Traditional](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhTW.md)
67 | * [French](https://github.com/porecreat/ruby-style-guide/blob/master/README-frFR.md)
68 |
69 | ## Table of Contents
70 |
71 | * [Source Code Layout](#source-code-layout)
72 | * [Syntax](#syntax)
73 | * [Naming](#naming)
74 | * [Comments](#comments)
75 | * [Comment Annotations](#comment-annotations)
76 | * [Classes](#classes)
77 | * [Exceptions](#exceptions)
78 | * [Collections](#collections)
79 | * [Strings](#strings)
80 | * [Regular Expressions](#regular-expressions)
81 | * [Percent Literals](#percent-literals)
82 | * [Metaprogramming](#metaprogramming)
83 | * [Misc](#misc)
84 |
85 | ## Source Code Layout
86 |
87 | > Nearly everybody is convinced that every style but their own is
88 | > ugly and unreadable. Leave out the "but their own" and they're
89 | > probably right...
90 | > -- Jerry Coffin (on indentation)
91 |
92 | * Use `UTF-8` as the source file encoding.
93 | * Use two **spaces** per indentation level. No hard tabs.
94 |
95 | ```Ruby
96 | # good
97 | def some_method
98 | do_something
99 | end
100 |
101 | # bad - four spaces
102 | def some_method
103 | do_something
104 | end
105 | ```
106 |
107 | * Use Unix-style line endings. (*BSD/Solaris/Linux/OSX users are covered by default,
108 | Windows users have to be extra careful.)
109 | * If you're using Git you might want to add the following
110 | configuration setting to protect your project from Windows line
111 | endings creeping in:
112 |
113 | $ git config --global core.autocrlf true
114 |
115 | * Use spaces around operators, after commas, colons and semicolons, around `{`
116 | and before `}`. Whitespace might be (mostly) irrelevant to the Ruby
117 | interpreter, but its proper use is the key to writing easily
118 | readable code.
119 |
120 | ```Ruby
121 | sum = 1 + 2
122 | a, b = 1, 2
123 | 1 > 2 ? true : false; puts 'Hi'
124 | [1, 2, 3].each { |e| puts e }
125 | ```
126 |
127 | The only exception is when using the exponent operator:
128 |
129 | ```Ruby
130 | # bad
131 | e = M * c ** 2
132 |
133 | # good
134 | e = M * c**2
135 | ```
136 |
137 | * No spaces after `(`, `[` or before `]`, `)`.
138 |
139 | ```Ruby
140 | some(arg).other
141 | [1, 2, 3].length
142 | ```
143 |
144 | * Indent `when` as deep as `case`. I know that many would disagree
145 | with this one, but it's the style established in both "The Ruby
146 | Programming Language" and "Programming Ruby".
147 |
148 | ```Ruby
149 | case
150 | when song.name == 'Misty'
151 | puts 'Not again!'
152 | when song.duration > 120
153 | puts 'Too long!'
154 | when Time.now.hour > 21
155 | puts "It's too late"
156 | else
157 | song.play
158 | end
159 |
160 | kind = case year
161 | when 1850..1889 then 'Blues'
162 | when 1890..1909 then 'Ragtime'
163 | when 1910..1929 then 'New Orleans Jazz'
164 | when 1930..1939 then 'Swing'
165 | when 1940..1950 then 'Bebop'
166 | else 'Jazz'
167 | end
168 | ```
169 |
170 | * Use empty lines between `def`s and to break up a method into logical
171 | paragraphs.
172 |
173 | ```Ruby
174 | def some_method
175 | data = initialize(options)
176 |
177 | data.manipulate!
178 |
179 | data.result
180 | end
181 |
182 | def some_method
183 | result
184 | end
185 | ```
186 |
187 | * Align the parameters of a method call if they span more than one line.
188 |
189 | ```Ruby
190 | # starting point (line is too long)
191 | def send_mail(source)
192 | Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
193 | end
194 |
195 | # bad (normal indent)
196 | def send_mail(source)
197 | Mailer.deliver(
198 | to: 'bob@example.com',
199 | from: 'us@example.com',
200 | subject: 'Important message',
201 | body: source.text)
202 | end
203 |
204 | # bad (double indent)
205 | def send_mail(source)
206 | Mailer.deliver(
207 | to: 'bob@example.com',
208 | from: 'us@example.com',
209 | subject: 'Important message',
210 | body: source.text)
211 | end
212 |
213 | # good
214 | def send_mail(source)
215 | Mailer.deliver(to: 'bob@example.com',
216 | from: 'us@example.com',
217 | subject: 'Important message',
218 | body: source.text)
219 | end
220 | ```
221 |
222 | * Add underscores to large numeric literals to improve their readability.
223 |
224 | ```Ruby
225 | # bad - how many 0s are there?
226 | num = 1000000
227 |
228 | # good - much easier to parse for the human brain
229 | num = 1_000_000
230 | ```
231 |
232 | * Use RDoc and its conventions for API documentation. Don't put an
233 | empty line between the comment block and the `def`.
234 | * Limit lines to 80 characters.
235 | * Avoid trailing whitespace.
236 |
237 | ## Syntax
238 |
239 | * Use `def` with parentheses when there are arguments. Omit the
240 | parentheses when the method doesn't accept any arguments.
241 |
242 | ```Ruby
243 | def some_method
244 | # body omitted
245 | end
246 |
247 | def some_method_with_arguments(arg1, arg2)
248 | # body omitted
249 | end
250 | ```
251 |
252 | * Never use `for`, unless you know exactly why. Most of the time iterators
253 | should be used instead. `for` is implemented in terms of `each` (so
254 | you're adding a level of indirection), but with a twist - `for`
255 | doesn't introduce a new scope (unlike `each`) and variables defined
256 | in its block will be visible outside it.
257 |
258 | ```Ruby
259 | arr = [1, 2, 3]
260 |
261 | # bad
262 | for elem in arr do
263 | puts elem
264 | end
265 |
266 | # good
267 | arr.each { |elem| puts elem }
268 | ```
269 |
270 | * Never use `then` for multi-line `if/unless`.
271 |
272 | ```Ruby
273 | # bad
274 | if some_condition then
275 | # body omitted
276 | end
277 |
278 | # good
279 | if some_condition
280 | # body omitted
281 | end
282 | ```
283 |
284 | * Favor the ternary operator(`?:`) over `if/then/else/end` constructs.
285 | It's more common and obviously more concise.
286 |
287 | ```Ruby
288 | # bad
289 | result = if some_condition then something else something_else end
290 |
291 | # good
292 | result = some_condition ? something : something_else
293 | ```
294 |
295 | * Use one expression per branch in a ternary operator. This
296 | also means that ternary operators must not be nested. Prefer
297 | `if/else` constructs in these cases.
298 |
299 | ```Ruby
300 | # bad
301 | some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
302 |
303 | # good
304 | if some_condition
305 | nested_condition ? nested_something : nested_something_else
306 | else
307 | something_else
308 | end
309 | ```
310 |
311 | * Never use `if x: ...` - it is removed in Ruby 1.9. Use
312 | the ternary operator instead.
313 |
314 | ```Ruby
315 | # bad
316 | result = if some_condition: something else something_else end
317 |
318 | # good
319 | result = some_condition ? something : something_else
320 | ```
321 |
322 | * Never use `if x; ...`. Use the ternary operator instead.
323 |
324 | * Use `when x then ...` for one-line cases. The alternative syntax
325 | `when x: ...` is removed in Ruby 1.9.
326 |
327 | * Never use `when x; ...`. See the previous rule.
328 |
329 | * Use `&&/||` for boolean expressions, `and/or` for control flow. (Rule
330 | of thumb: If you have to use outer parentheses, you are using the
331 | wrong operators.)
332 |
333 | ```Ruby
334 | # boolean expression
335 | if some_condition && some_other_condition
336 | do_something
337 | end
338 |
339 | # control flow
340 | document.saved? or document.save!
341 | ```
342 |
343 | * Avoid multi-line `?:` (the ternary operator); use `if/unless` instead.
344 |
345 | * Favor modifier `if/unless` usage when you have a single-line
346 | body. Another good alternative is the usage of control flow `and/or`.
347 |
348 | ```Ruby
349 | # bad
350 | if some_condition
351 | do_something
352 | end
353 |
354 | # good
355 | do_something if some_condition
356 |
357 | # another good option
358 | some_condition and do_something
359 | ```
360 |
361 | * Favor `unless` over `if` for negative conditions (or control
362 | flow `or`).
363 |
364 | ```Ruby
365 | # bad
366 | do_something if !some_condition
367 |
368 | # good
369 | do_something unless some_condition
370 |
371 | # another good option
372 | some_condition or do_something
373 | ```
374 |
375 | * Never use `unless` with `else`. Rewrite these with the positive case first.
376 |
377 | ```Ruby
378 | # bad
379 | unless success?
380 | puts 'failure'
381 | else
382 | puts 'success'
383 | end
384 |
385 | # good
386 | if success?
387 | puts 'success'
388 | else
389 | puts 'failure'
390 | end
391 | ```
392 |
393 | * Don't use parentheses around the condition of an `if/unless/while`,
394 | unless the condition contains an assignment (see "Using the return
395 | value of `=`" below).
396 |
397 | ```Ruby
398 | # bad
399 | if (x > 10)
400 | # body omitted
401 | end
402 |
403 | # good
404 | if x > 10
405 | # body omitted
406 | end
407 |
408 | # ok
409 | if (x = self.next_value)
410 | # body omitted
411 | end
412 | ```
413 |
414 | * Favor modifier `while/until` usage when you have a single-line
415 | body.
416 |
417 | ```Ruby
418 | # bad
419 | while some_condition
420 | do_something
421 | end
422 |
423 | # good
424 | do_something while some_condition
425 | ```
426 |
427 | * Favor `until` over `while` for negative conditions.
428 |
429 | ```Ruby
430 | # bad
431 | do_something while !some_condition
432 |
433 | # good
434 | do_something until some_condition
435 | ```
436 |
437 | * Omit parentheses around parameters for methods that are part of an
438 | internal DSL (e.g. Rake, Rails, RSpec), methods that have
439 | "keyword" status in Ruby (e.g. `attr_reader`, `puts`) and attribute
440 | access methods. Use parentheses around the arguments of all other
441 | method invocations.
442 |
443 | ```Ruby
444 | class Person
445 | attr_reader :name, :age
446 |
447 | # omitted
448 | end
449 |
450 | temperance = Person.new('Temperance', 30)
451 | temperance.name
452 |
453 | puts temperance.age
454 |
455 | x = Math.sin(y)
456 | array.delete(e)
457 | ```
458 |
459 | * Prefer `{...}` over `do...end` for single-line blocks. Avoid using
460 | `{...}` for multi-line blocks (multiline chaining is always
461 | ugly). Always use `do...end` for "control flow" and "method
462 | definitions" (e.g. in Rakefiles and certain DSLs). Avoid `do...end`
463 | when chaining.
464 |
465 | ```Ruby
466 | names = ['Bozhidar', 'Steve', 'Sarah']
467 |
468 | # good
469 | names.each { |name| puts name }
470 |
471 | # bad
472 | names.each do |name|
473 | puts name
474 | end
475 |
476 | # good
477 | names.select { |name| name.start_with?('S') }.map { |name| name.upcase }
478 |
479 | # bad
480 | names.select do |name|
481 | name.start_with?('S')
482 | end.map { |name| name.upcase }
483 | ```
484 |
485 | Some will argue that multiline chaining would look OK with the use of {...}, but they should
486 | ask themselves - is this code really readable and can the blocks' contents be extracted into
487 | nifty methods?
488 |
489 | * Avoid `return` where not required for flow of control.
490 |
491 | ```Ruby
492 | # bad
493 | def some_method(some_arr)
494 | return some_arr.size
495 | end
496 |
497 | # good
498 | def some_method(some_arr)
499 | some_arr.size
500 | end
501 | ```
502 |
503 | * Avoid `self` where not required. (It is only required when calling a self write accessor.)
504 |
505 | ```Ruby
506 | # bad
507 | def ready?
508 | if self.last_reviewed_at > self.last_updated_at
509 | self.worker.update(self.content, self.options)
510 | self.status = :in_progress
511 | end
512 | self.status == :verified
513 | end
514 |
515 | # good
516 | def ready?
517 | if last_reviewed_at > last_updated_at
518 | worker.update(content, options)
519 | self.status = :in_progress
520 | end
521 | status == :verified
522 | end
523 | ```
524 |
525 | * As a corollary, avoid shadowing methods with local variables unless they are both equivalent.
526 |
527 | ```Ruby
528 | class Foo
529 | attr_accessor :options
530 |
531 | # ok
532 | def initialize(options)
533 | self.options = options
534 | # both options and self.options are equivalent here
535 | end
536 |
537 | # bad
538 | def do_something(options = {})
539 | unless options[:when] == :later
540 | output(self.options[:message])
541 | end
542 | end
543 |
544 | # good
545 | def do_something(params = {})
546 | unless params[:when] == :later
547 | output(options[:message])
548 | end
549 | end
550 | end
551 | ```
552 |
553 | * Use spaces around the `=` operator when assigning default values to method parameters:
554 |
555 | ```Ruby
556 | # bad
557 | def some_method(arg1=:default, arg2=nil, arg3=[])
558 | # do something...
559 | end
560 |
561 | # good
562 | def some_method(arg1 = :default, arg2 = nil, arg3 = [])
563 | # do something...
564 | end
565 | ```
566 |
567 | While several Ruby books suggest the first style, the second is much more prominent
568 | in practice (and arguably a bit more readable).
569 |
570 | * Avoid line continuation (\\) where not required. In practice, avoid using
571 | line continuations at all.
572 |
573 | ```Ruby
574 | # bad
575 | result = 1 - \
576 | 2
577 |
578 | # good (but still ugly as hell)
579 | result = 1 \
580 | - 2
581 | ```
582 |
583 | * Using the return value of `=` (an assignment) is ok, but surround the
584 | assignment with parentheses.
585 |
586 | ```Ruby
587 | # good - shows intended use of assignment
588 | if (v = array.grep(/foo/)) ...
589 |
590 | # bad
591 | if v = array.grep(/foo/) ...
592 |
593 | # also good - shows intended use of assignment and has correct precedence.
594 | if (v = self.next_value) == 'hello' ...
595 | ```
596 |
597 | * Use `||=` freely to initialize variables.
598 |
599 | ```Ruby
600 | # set name to Bozhidar, only if it's nil or false
601 | name ||= 'Bozhidar'
602 | ```
603 |
604 | * Don't use `||=` to initialize boolean variables. (Consider what
605 | would happen if the current value happened to be `false`.)
606 |
607 | ```Ruby
608 | # bad - would set enabled to true even if it was false
609 | enabled ||= true
610 |
611 | # good
612 | enabled = true if enabled.nil?
613 | ```
614 |
615 | * Avoid using Perl-style special variables (like `$0-9`, `$``,
616 | etc. ). They are quite cryptic and their use in anything but
617 | one-liner scripts is discouraged.
618 |
619 | * Never put a space between a method name and the opening parenthesis.
620 |
621 | ```Ruby
622 | # bad
623 | f (3 + 2) + 1
624 |
625 | # good
626 | f(3 + 2) + 1
627 | ```
628 |
629 | * If the first argument to a method begins with an open parenthesis,
630 | always use parentheses in the method invocation. For example, write
631 | `f((3 + 2) + 1)`.
632 |
633 | * Always run the Ruby interpreter with the `-w` option so it will warn
634 | you if you forget either of the rules above!
635 |
636 | * The new hash literal syntax is preferred in Ruby 1.9 when your hash keys are symbols.
637 |
638 | ```Ruby
639 | # bad
640 | hash = { :one => 1, :two => 2 }
641 |
642 | # good
643 | hash = { one: 1, two: 2 }
644 | ```
645 |
646 | * The new lambda literal syntax is preferred in Ruby 1.9.
647 |
648 | ```Ruby
649 | # bad
650 | lambda = lambda { |a, b| a + b }
651 | lambda.call(1, 2)
652 |
653 | # good
654 | lambda = ->(a, b) { a + b }
655 | lambda.(1, 2)
656 | ```
657 |
658 | * Use `_` for unused block parameters.
659 |
660 | ```Ruby
661 | # bad
662 | result = hash.map { |k, v| v + 1 }
663 |
664 | # good
665 | result = hash.map { |_, v| v + 1 }
666 | ```
667 |
668 | ## Naming
669 |
670 | > The only real difficulties in programming are cache invalidation and
671 | > naming things.
672 | > -- Phil Karlton
673 |
674 | * Use `snake_case` for methods and variables.
675 | * Use `CamelCase` for classes and modules. (Keep acronyms like HTTP,
676 | RFC, XML uppercase.)
677 | * Use `SCREAMING_SNAKE_CASE` for other constants.
678 | * The names of predicate methods (methods that return a boolean value)
679 | should end in a question mark.
680 | (i.e. `Array#empty?`).
681 | * The names of potentially "dangerous" methods (i.e. methods that modify `self` or the
682 | arguments, `exit!` (doesn't run the finalizers like `exit` does), etc.) should end with an exclamation mark if
683 | there exists a safe version of that *dangerous* method.
684 |
685 | ```Ruby
686 | # bad - there is not matching 'safe' method
687 | class Person
688 | def update!
689 | end
690 | end
691 |
692 | # good
693 | class Person
694 | def update
695 | end
696 | end
697 |
698 | # good
699 | class Person
700 | def update!
701 | end
702 |
703 | def update
704 | end
705 | end
706 | ```
707 |
708 | * Define the non-bang (safe) method in terms of the bang (dangerous)
709 | one if possible.
710 |
711 | ```Ruby
712 | class Array
713 | def flatten_once!
714 | res = []
715 |
716 | each do |e|
717 | [*e].each { |f| res << f }
718 | end
719 |
720 | replace(res)
721 | end
722 |
723 | def flatten_once
724 | dup.flatten_once!
725 | end
726 | end
727 | ```
728 |
729 | * When using `reduce` with short blocks, name the arguments `|a, e|`
730 | (accumulator, element).
731 | * When defining binary operators, name the argument `other`.
732 |
733 | ```Ruby
734 | def +(other)
735 | # body omitted
736 | end
737 | ```
738 |
739 | * Prefer `map` over `collect`, `find` over `detect`, `select` over
740 | `find_all`, `reduce` over `inject` and `size` over `length`. This is
741 | not a hard requirement; if the use of the alias enhances
742 | readability, it's ok to use it. The rhyming methods are inherited from
743 | Smalltalk and are not common in other programming languages. The
744 | reason the use of `select` is encouraged over `find_all` is that it
745 | goes together nicely with `reject` and its name is pretty self-explanatory.
746 |
747 | * Use `flat_map` instead of `map` + `flatten`.
748 |
749 | ```Ruby
750 | # bad
751 | all_songs = users.map(&:songs).flatten.uniq
752 |
753 | # good
754 | all_songs = users.flat_map(&:songs).uniq
755 | ```
756 |
757 | ## Comments
758 |
759 | > Good code is its own best documentation. As you're about to add a
760 | > comment, ask yourself, "How can I improve the code so that this
761 | > comment isn't needed?" Improve the code and then document it to make
762 | > it even clearer.
763 | > -- Steve McConnell
764 |
765 | * Write self-documenting code and ignore the rest of this section. Seriously!
766 | * Comments longer than a word are capitalized and use punctuation. Use [one
767 | space](http://en.wikipedia.org/wiki/Sentence_spacing) after periods.
768 | * Avoid superfluous comments.
769 |
770 | ```Ruby
771 | # bad
772 | counter += 1 # increments counter by one
773 | ```
774 |
775 | * Keep existing comments up-to-date. An outdated is worse than no comment
776 | at all.
777 |
778 | > Good code is like a good joke - it needs no explanation.
779 | > -- Russ Olsen
780 |
781 | * Avoid writing comments to explain bad code. Refactor the code to
782 | make it self-explanatory. (Do or do not - there is no try. --Yoda)
783 |
784 | ### Comment Annotations
785 |
786 | * Annotations should usually be written on the line immediately above
787 | the relevant code.
788 | * The annotation keyword is followed by a colon and a space, then a note
789 | describing the problem.
790 | * If multiple lines are required to describe the problem, subsequent
791 | lines should be indented two spaces after the `#`.
792 |
793 | ```Ruby
794 | def bar
795 | # FIXME: This has crashed occasionally since v3.2.1. It may
796 | # be related to the BarBazUtil upgrade.
797 | baz(:quux)
798 | end
799 | ```
800 |
801 | * In cases where the problem is so obvious that any documentation would
802 | be redundant, annotations may be left at the end of the offending line
803 | with no note. This usage should be the exception and not the rule.
804 |
805 | ```Ruby
806 | def bar
807 | sleep 100 # OPTIMIZE
808 | end
809 | ```
810 |
811 | * Use `TODO` to note missing features or functionality that should be
812 | added at a later date.
813 | * Use `FIXME` to note broken code that needs to be fixed.
814 | * Use `OPTIMIZE` to note slow or inefficient code that may cause
815 | performance problems.
816 | * Use `HACK` to note code smells where questionable coding practices
817 | were used and should be refactored away.
818 | * Use `REVIEW` to note anything that should be looked at to confirm it
819 | is working as intended. For example: `REVIEW: Are we sure this is how the
820 | client does X currently?`
821 | * Use other custom annotation keywords if it feels appropriate, but be
822 | sure to document them in your project's `README` or similar.
823 |
824 | ## Classes
825 |
826 | * When designing class hierarchies make sure that they conform to the
827 | [Liskov Substitution Principle](http://en.wikipedia.org/wiki/Liskov_substitution_principle).
828 | * Try to make your classes as
829 | SOLID
830 | as possible.
831 | * Always supply a proper `to_s` method for classes that represent
832 | domain objects.
833 |
834 | ```Ruby
835 | class Person
836 | attr_reader :first_name, :last_name
837 |
838 | def initialize(first_name, last_name)
839 | @first_name = first_name
840 | @last_name = last_name
841 | end
842 |
843 | def to_s
844 | "#@first_name #@last_name"
845 | end
846 | end
847 | ```
848 |
849 | * Use the `attr` family of functions to define trivial accessors or
850 | mutators.
851 |
852 | ```Ruby
853 | # bad
854 | class Person
855 | def initialize(first_name, last_name)
856 | @first_name = first_name
857 | @last_name = last_name
858 | end
859 |
860 | def first_name
861 | @first_name
862 | end
863 |
864 | def last_name
865 | @last_name
866 | end
867 | end
868 |
869 | # good
870 | class Person
871 | attr_reader :first_name, :last_name
872 |
873 | def initialize(first_name, last_name)
874 | @first_name = first_name
875 | @last_name = last_name
876 | end
877 | end
878 | ```
879 | * Consider using `Struct.new`, which defines the trivial accessors,
880 | constructor and comparison operators for you.
881 |
882 | ```Ruby
883 | # good
884 | class Person
885 | attr_reader :first_name, :last_name
886 |
887 | def initialize(first_name, last_name)
888 | @first_name = first_name
889 | @last_name = last_name
890 | end
891 | end
892 |
893 | # better
894 | class Person < Struct.new(:first_name, :last_name)
895 | end
896 | ````
897 |
898 | * Consider adding factory methods to provide additional sensible ways
899 | to create instances of a particular class.
900 |
901 | ```Ruby
902 | class Person
903 | def self.create(options_hash)
904 | # body omitted
905 | end
906 | end
907 | ```
908 |
909 | * Prefer [duck-typing](http://en.wikipedia.org/wiki/Duck_typing) over inheritance.
910 |
911 | ```Ruby
912 | # bad
913 | class Animal
914 | # abstract method
915 | def speak
916 | end
917 | end
918 |
919 | # extend superclass
920 | class Duck < Animal
921 | def speak
922 | puts 'Quack! Quack'
923 | end
924 | end
925 |
926 | # extend superclass
927 | class Dog < Animal
928 | def speak
929 | puts 'Bau! Bau!'
930 | end
931 | end
932 |
933 | # good
934 | class Duck
935 | def speak
936 | puts 'Quack! Quack'
937 | end
938 | end
939 |
940 | class Dog
941 | def speak
942 | puts 'Bau! Bau!'
943 | end
944 | end
945 | ```
946 |
947 | * Avoid the usage of class (`@@`) variables due to their "nasty" behavior
948 | in inheritance.
949 |
950 | ```Ruby
951 | class Parent
952 | @@class_var = 'parent'
953 |
954 | def self.print_class_var
955 | puts @@class_var
956 | end
957 | end
958 |
959 | class Child < Parent
960 | @@class_var = 'child'
961 | end
962 |
963 | Parent.print_class_var # => will print "child"
964 | ```
965 |
966 | As you can see all the classes in a class hierarchy actually share one
967 | class variable. Class instance variables should usually be preferred
968 | over class variables.
969 |
970 | * Assign proper visibility levels to methods (`private`, `protected`)
971 | in accordance with their intended usage. Don't go off leaving
972 | everything `public` (which is the default). After all we're coding
973 | in *Ruby* now, not in *Python*.
974 | * Indent the `public`, `protected`, and `private` methods as much the
975 | method definitions they apply to. Leave one blank line above the
976 | visibility modifier
977 | and one blank line below in order to emphasize that it applies to all
978 | methods below it.
979 |
980 | ```Ruby
981 | class SomeClass
982 | def public_method
983 | # ...
984 | end
985 |
986 | private
987 |
988 | def private_method
989 | # ...
990 | end
991 |
992 | def another_private_method
993 | # ...
994 | end
995 | end
996 | ```
997 |
998 | * Use `def self.method` to define singleton methods. This makes the code
999 | easier to refactor since the class name is not repeated.
1000 |
1001 | ```Ruby
1002 | class TestClass
1003 | # bad
1004 | def TestClass.some_method
1005 | # body omitted
1006 | end
1007 |
1008 | # good
1009 | def self.some_other_method
1010 | # body omitted
1011 | end
1012 |
1013 | # Also possible and convenient when you
1014 | # have to define many singleton methods.
1015 | class << self
1016 | def first_method
1017 | # body omitted
1018 | end
1019 |
1020 | def second_method_etc
1021 | # body omitted
1022 | end
1023 | end
1024 | end
1025 | ```
1026 |
1027 | ## Exceptions
1028 |
1029 | * Signal exceptions using the `fail` method. Use `raise` only when
1030 | catching an exception and re-raising it (because here you're not
1031 | failing, but explicitly and purposefully raising an exception).
1032 |
1033 | ```Ruby
1034 | begin
1035 | fail 'Oops';
1036 | rescue => error
1037 | raise if error.message != 'Oops'
1038 | end
1039 | ```
1040 |
1041 | * Never return from an `ensure` block. If you explicitly return from a
1042 | method inside an `ensure` block, the return will take precedence over
1043 | any exception being raised, and the method will return as if no
1044 | exception had been raised at all. In effect, the exception will be
1045 | silently thrown away.
1046 |
1047 | ```Ruby
1048 | def foo
1049 | begin
1050 | fail
1051 | ensure
1052 | return 'very bad idea'
1053 | end
1054 | end
1055 | ```
1056 |
1057 | * Use *implicit begin blocks* where possible.
1058 |
1059 | ```Ruby
1060 | # bad
1061 | def foo
1062 | begin
1063 | # main logic goes here
1064 | rescue
1065 | # failure handling goes here
1066 | end
1067 | end
1068 |
1069 | # good
1070 | def foo
1071 | # main logic goes here
1072 | rescue
1073 | # failure handling goes here
1074 | end
1075 | ```
1076 |
1077 | * Mitigate the proliferation of `begin` blocks by using
1078 | *contingency methods* (a term coined by Avdi Grimm).
1079 |
1080 | ```Ruby
1081 | # bad
1082 | begin
1083 | something_that_might_fail
1084 | rescue IOError
1085 | # handle IOError
1086 | end
1087 |
1088 | begin
1089 | something_else_that_might_fail
1090 | rescue IOError
1091 | # handle IOError
1092 | end
1093 |
1094 | # good
1095 | def with_io_error_handling
1096 | yield
1097 | rescue IOError
1098 | # handle IOError
1099 | end
1100 |
1101 | with_io_error_handling { something_that_might_fail }
1102 |
1103 | with_io_error_handling { something_else_that_might_fail }
1104 | ```
1105 |
1106 | * Don't suppress exceptions.
1107 |
1108 | ```Ruby
1109 | # bad
1110 | begin
1111 | # an exception occurs here
1112 | rescue SomeError
1113 | # the rescue clause does absolutely nothing
1114 | end
1115 |
1116 | # bad
1117 | do_something rescue nil
1118 | ```
1119 |
1120 | * Avoid using `rescue` in its modifier form.
1121 |
1122 | ```Ruby
1123 | # bad - this catches all StandardError exceptions
1124 | do_something rescue nil
1125 | ```
1126 |
1127 |
1128 | * Don't use exceptions for flow of control.
1129 |
1130 | ```Ruby
1131 | # bad
1132 | begin
1133 | n / d
1134 | rescue ZeroDivisionError
1135 | puts 'Cannot divide by 0!'
1136 | end
1137 |
1138 | # good
1139 | if d.zero?
1140 | puts 'Cannot divide by 0!'
1141 | else
1142 | n / d
1143 | end
1144 | ```
1145 |
1146 | * Avoid rescuing the `Exception` class. This will trap signals and calls to
1147 | `exit`, requiring you to `kill -9` the process.
1148 |
1149 | ```Ruby
1150 | # bad
1151 | begin
1152 | # calls to exit and kill signals will be caught (except kill -9)
1153 | exit
1154 | rescue Exception
1155 | puts "you didn't really want to exit, right?"
1156 | # exception handling
1157 | end
1158 |
1159 | # good
1160 | begin
1161 | # a blind rescue rescues from StandardError, not Exception as many
1162 | # programmers assume.
1163 | rescue => e
1164 | # exception handling
1165 | end
1166 |
1167 | # also good
1168 | begin
1169 | # an exception occurs here
1170 |
1171 | rescue StandardError => e
1172 | # exception handling
1173 | end
1174 |
1175 | ```
1176 |
1177 | * Put more specific exceptions higher up the rescue chain, otherwise
1178 | they'll never be rescued from.
1179 |
1180 | ```Ruby
1181 | # bad
1182 | begin
1183 | # some code
1184 | rescue Exception => e
1185 | # some handling
1186 | rescue StandardError => e
1187 | # some handling
1188 | end
1189 |
1190 | # good
1191 | begin
1192 | # some code
1193 | rescue StandardError => e
1194 | # some handling
1195 | rescue Exception => e
1196 | # some handling
1197 | end
1198 | ```
1199 |
1200 | * Release external resources obtained by your program in an ensure
1201 | block.
1202 |
1203 | ```Ruby
1204 | f = File.open('testfile')
1205 | begin
1206 | # .. process
1207 | rescue
1208 | # .. handle error
1209 | ensure
1210 | f.close unless f.nil?
1211 | end
1212 | ```
1213 |
1214 | * Favor the use of exceptions for the standard library over
1215 | introducing new exception classes.
1216 |
1217 | ## Collections
1218 |
1219 | * Prefer literal array and hash creation notation (unless you need to
1220 | pass parameters to their constructors, that is).
1221 |
1222 | ```Ruby
1223 | # bad
1224 | arr = Array.new
1225 | hash = Hash.new
1226 |
1227 | # good
1228 | arr = []
1229 | hash = {}
1230 | ```
1231 |
1232 | * Prefer `%w` to the literal array syntax when you need an array of
1233 | strings.
1234 |
1235 | ```Ruby
1236 | # bad
1237 | STATES = ['draft', 'open', 'closed']
1238 |
1239 | # good
1240 | STATES = %w(draft open closed)
1241 | ```
1242 |
1243 | * Avoid the creation of huge gaps in arrays.
1244 |
1245 | ```Ruby
1246 | arr = []
1247 | arr[100] = 1 # now you have an array with lots of nils
1248 | ```
1249 |
1250 | * Use `Set` instead of `Array` when dealing with unique elements. `Set`
1251 | implements a collection of unordered values with no duplicates. This
1252 | is a hybrid of `Array`'s intuitive inter-operation facilities and
1253 | `Hash`'s fast lookup.
1254 | * Prefer symbols instead of strings as hash keys.
1255 |
1256 | ```Ruby
1257 | # bad
1258 | hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
1259 |
1260 | # good
1261 | hash = { one: 1, two: 2, three: 3 }
1262 | ```
1263 |
1264 | * Avoid the use of mutable objects as hash keys.
1265 | * The new hash literal syntax is preferred in Ruby 1.9 when your hash keys are symbols.
1266 |
1267 | ```Ruby
1268 | # bad
1269 | hash = { :one => 1, :two => 2, :three => 3 }
1270 |
1271 | # good
1272 | hash = { one: 1, two: 2, three: 3 }
1273 | ```
1274 |
1275 | * Use `fetch` when dealing with hash keys that should be present.
1276 |
1277 | ```Ruby
1278 | heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
1279 | # bad - if we make a mistake we might not spot it right away
1280 | heroes[:batman] # => "Bruce Wayne"
1281 | heroes[:supermann] # => nil
1282 |
1283 | # good - fetch raises a KeyError making the problem obvious
1284 | heroes.fetch(:supermann)
1285 | ```
1286 |
1287 | * Rely on the fact that hashes in Ruby 1.9 are ordered.
1288 | * Never modify a collection while traversing it.
1289 |
1290 | ## Strings
1291 |
1292 | * Prefer string interpolation instead of string concatenation:
1293 |
1294 | ```Ruby
1295 | # bad
1296 | email_with_name = user.name + ' <' + user.email + '>'
1297 |
1298 | # good
1299 | email_with_name = "#{user.name} <#{user.email}>"
1300 | ```
1301 |
1302 | * Consider padding string interpolation code with space. It more clearly sets the
1303 | code apart from the string.
1304 |
1305 | ```Ruby
1306 | "#{ user.last_name }, #{ user.first_name }"
1307 | ```
1308 |
1309 | * Prefer single-quoted strings when you don't need string interpolation or
1310 | special symbols such as `\t`, `\n`, `'`, etc.
1311 |
1312 | ```Ruby
1313 | # bad
1314 | name = "Bozhidar"
1315 |
1316 | # good
1317 | name = 'Bozhidar'
1318 | ```
1319 |
1320 | * Don't use `{}` around instance variables being interpolated into a
1321 | string.
1322 |
1323 | ```Ruby
1324 | class Person
1325 | attr_reader :first_name, :last_name
1326 |
1327 | def initialize(first_name, last_name)
1328 | @first_name = first_name
1329 | @last_name = last_name
1330 | end
1331 |
1332 | # bad
1333 | def to_s
1334 | "#{@first_name} #{@last_name}"
1335 | end
1336 |
1337 | # good
1338 | def to_s
1339 | "#@first_name #@last_name"
1340 | end
1341 | end
1342 | ```
1343 |
1344 | * Avoid using `String#+` when you need to construct large data chunks.
1345 | Instead, use `String#<<`. Concatenation mutates the string instance in-place
1346 | and is always faster than `String#+`, which creates a bunch of new string objects.
1347 |
1348 | ```Ruby
1349 | # good and also fast
1350 | html = ''
1351 | html << 'Page title
'
1352 |
1353 | paragraphs.each do |paragraph|
1354 | html << "#{paragraph}
"
1355 | end
1356 | ```
1357 |
1358 | ## Regular Expressions
1359 |
1360 | > Some people, when confronted with a problem, think
1361 | > "I know, I'll use regular expressions." Now they have two problems.
1362 | > -- Jamie Zawinski
1363 |
1364 | * Don't use regular expressions if you just need plain text search in string:
1365 | `string['text']`
1366 | * For simple constructions you can use regexp directly through string index.
1367 |
1368 | ```Ruby
1369 | match = string[/regexp/] # get content of matched regexp
1370 | first_group = string[/text(grp)/, 1] # get content of captured group
1371 | string[/text (grp)/, 1] = 'replace' # string => 'text replace'
1372 | ```
1373 |
1374 | * Use non-capturing groups when you don't use captured result of parentheses.
1375 |
1376 | ```Ruby
1377 | /(first|second)/ # bad
1378 | /(?:first|second)/ # good
1379 | ```
1380 |
1381 | * Avoid using $1-9 as it can be hard to track what they contain. Named groups
1382 | can be used instead.
1383 |
1384 | ```Ruby
1385 | # bad
1386 | /(regexp)/ =~ string
1387 | ...
1388 | process $1
1389 |
1390 | # good
1391 | /(?regexp)/ =~ string
1392 | ...
1393 | process meaningful_var
1394 | ```
1395 |
1396 | * Character classes have only a few special characters you should care about:
1397 | `^`, `-`, `\`, `]`, so don't escape `.` or brackets in `[]`.
1398 |
1399 | * Be careful with `^` and `$` as they match start/end of line, not string endings.
1400 | If you want to match the whole string use: `\A` and `\z` (not to be
1401 | confused with `\Z` which is the equivalent of `/\n?\z/`).
1402 |
1403 | ```Ruby
1404 | string = "some injection\nusername"
1405 | string[/^username$/] # matches
1406 | string[/\Ausername\z/] # don't match
1407 | ```
1408 |
1409 | * Use `x` modifier for complex regexps. This makes them more readable and you
1410 | can add some useful comments. Just be careful as spaces are ignored.
1411 |
1412 | ```Ruby
1413 | regexp = %r{
1414 | start # some text
1415 | \s # white space char
1416 | (group) # first group
1417 | (?:alt1|alt2) # some alternation
1418 | end
1419 | }x
1420 | ```
1421 |
1422 | * For complex replacements `sub`/`gsub` can be used with block or hash.
1423 |
1424 | ## Percent Literals
1425 |
1426 | * Use `%w` freely.
1427 |
1428 | ```Ruby
1429 | STATES = %w(draft open closed)
1430 | ```
1431 |
1432 | * Use `%()` for single-line strings which require both interpolation
1433 | and embedded double-quotes. For multi-line strings, prefer heredocs.
1434 |
1435 | ```Ruby
1436 | # bad (no interpolation needed)
1437 | %(Some text
)
1438 | # should be 'Some text
'
1439 |
1440 | # bad (no double-quotes)
1441 | %(This is #{quality} style)
1442 | # should be "This is #{quality} style"
1443 |
1444 | # bad (multiple lines)
1445 | %(\n#{exclamation}\n
)
1446 | # should be a heredoc.
1447 |
1448 | # good (requires interpolation, has quotes, single line)
1449 | %(#{name} | )
1450 | ```
1451 |
1452 | * Use `%r` only for regular expressions matching *more than* one '/' character.
1453 |
1454 | ```Ruby
1455 | # bad
1456 | %r(\s+)
1457 |
1458 | # still bad
1459 | %r(^/(.*)$)
1460 | # should be /^\/(.*)$/
1461 |
1462 | # good
1463 | %r(^/blog/2011/(.*)$)
1464 | ```
1465 |
1466 | * Avoid `%q`, `%Q`, `%x`, `%s`, and `%W`.
1467 |
1468 | * Prefer `()` as delimiters for all `%` literals.
1469 |
1470 | ## Metaprogramming
1471 |
1472 | * Avoid needless metaprogramming.
1473 |
1474 | * Do not mess around in core classes when writing libraries.
1475 | (Do not monkey-patch them.)
1476 |
1477 | * The block form of `class_eval` is preferable to the string-interpolated form.
1478 | - when you use the string-interpolated form, always supply `__FILE__` and `__LINE__`, so that your backtraces make sense:
1479 |
1480 | ```ruby
1481 | class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__
1482 | ```
1483 |
1484 | - `define_method` is preferable to `class_eval{ def ... }`
1485 |
1486 | * When using `class_eval` (or other `eval`) with string interpolation, add a comment block showing its appearance if interpolated (a practice I learned from the Rails code):
1487 |
1488 | ```ruby
1489 | # from activesupport/lib/active_support/core_ext/string/output_safety.rb
1490 | UNSAFE_STRING_METHODS.each do |unsafe_method|
1491 | if 'String'.respond_to?(unsafe_method)
1492 | class_eval <<-EOT, __FILE__, __LINE__ + 1
1493 | def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
1494 | to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)
1495 | end # end
1496 |
1497 | def #{unsafe_method}!(*args) # def capitalize!(*args)
1498 | @dirty = true # @dirty = true
1499 | super # super
1500 | end # end
1501 | EOT
1502 | end
1503 | end
1504 | ```
1505 |
1506 | * avoid using `method_missing` for metaprogramming. Backtraces become messy; the behavior is not listed in `#methods`; misspelled method calls might silently work (`nukes.launch_state = false`). Consider using delegation, proxy, or `define_method` instead. If you must, use `method_missing`,
1507 | - be sure to [also define `respond_to_missing?`](http://blog.marc-andre.ca/2010/11/methodmissing-politely.html)
1508 | - only catch methods with a well-defined prefix, such as `find_by_*` -- make your code as assertive as possible.
1509 | - call `super` at the end of your statement
1510 | - delegate to assertive, non-magical methods:
1511 |
1512 | ```ruby
1513 | # bad
1514 | def method_missing?(meth, *args, &block)
1515 | if /^find_by_(?.*)/ =~ meth
1516 | # ... lots of code to do a find_by
1517 | else
1518 | super
1519 | end
1520 | end
1521 |
1522 | # good
1523 | def method_missing?(meth, *args, &block)
1524 | if /^find_by_(?.*)/ =~ meth
1525 | find_by(prop, *args, &block)
1526 | else
1527 | super
1528 | end
1529 | end
1530 |
1531 | # best of all, though, would to define_method as each findable attribute is declared
1532 | ```
1533 |
1534 | ## Misc
1535 |
1536 | * Write `ruby -w` safe code.
1537 | * Avoid hashes as optional parameters. Does the method do too much?
1538 | * Avoid methods longer than 10 LOC (lines of code). Ideally, most methods will be shorter than
1539 | 5 LOC. Empty lines do not contribute to the relevant LOC.
1540 | * Avoid parameter lists longer than three or four parameters.
1541 | * If you really need "global" methods, add them to Kernel
1542 | and make them private.
1543 | * Use class instance variables instead of global variables.
1544 |
1545 | ```Ruby
1546 | #bad
1547 | $foo_bar = 1
1548 |
1549 | #good
1550 | class Foo
1551 | class << self
1552 | attr_accessor :bar
1553 | end
1554 | end
1555 |
1556 | Foo.bar = 1
1557 | ```
1558 |
1559 | * Avoid `alias` when `alias_method` will do.
1560 | * Use `OptionParser` for parsing complex command line options and
1561 | `ruby -s` for trivial command line options.
1562 | * Code in a functional way, avoiding mutation when that makes sense.
1563 | * Do not mutate arguments unless that is the purpose of the method.
1564 | * Avoid more than three levels of block nesting.
1565 | * Be consistent. In an ideal world, be consistent with these guidelines.
1566 | * Use common sense.
1567 |
1568 | # Contributing
1569 |
1570 | Nothing written in this guide is set in stone. It's my desire to work
1571 | together with everyone interested in Ruby coding style, so that we could
1572 | ultimately create a resource that will be beneficial to the entire Ruby
1573 | community.
1574 |
1575 | Feel free to open tickets or send pull requests with improvements. Thanks in
1576 | advance for your help!
1577 |
1578 | # Spread the Word
1579 |
1580 | A community-driven style guide is of little use to a community that
1581 | doesn't know about its existence. Tweet about the guide, share it with
1582 | your friends and colleagues. Every comment, suggestion or opinion we
1583 | get makes the guide just a little bit better. And we want to have the
1584 | best possible guide, don't we?
1585 |
--------------------------------------------------------------------------------