├── .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 | --------------------------------------------------------------------------------