├── .gitattributes
├── CONTRIBUTING.md
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.md whitespace=trailing-space,tab-in-indent
2 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | * [Fork](https://help.github.com/articles/fork-a-repo) the project on GitHub.
2 | * Make your feature addition or bug fix in a feature branch. (Include a description of your changes)
3 | * Push your feature branch to GitHub.
4 | * Send a [Pull Request](https://help.github.com/articles/using-pull-requests).
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deprecated
2 |
3 | This fork of the guide is deprecated.
4 | Please read the opensource [Ruby style guide](https://github.com/bbatsov/ruby-style-guide) instead.
5 |
6 | The README below is left only as reference but will not be updated and PR
7 | are not welcomed.
8 |
9 | ***
10 |
11 | # Prelude
12 |
13 | > Style is what separates the good from the great.
14 | > -- Bozhidar Batsov
15 |
16 | One thing has always bothered me as Ruby developer - Python developers
17 | have a great programming style reference
18 | ([PEP-8](http://www.python.org/dev/peps/pep-0008/)) and we never got
19 | an official guide, documenting Ruby coding style and best
20 | practices. And I do believe that style matters. I also believe that
21 | such fine fellows, like us Ruby developers, should be quite capable to
22 | produce this coveted document.
23 |
24 | This guide started its life as our internal company Ruby coding guidelines
25 | (written by yours truly). At some point I decided that the work I was
26 | doing might be interesting to members of the Ruby community in general
27 | and that the world had little need for another internal company
28 | guideline. But the world could certainly benefit from a
29 | community-driven and community-sanctioned set of practices, idioms and
30 | style prescriptions for Ruby programming.
31 |
32 | Since the inception of the guide I've received a lot of feedback from
33 | members of the exceptional Ruby community around the world. Thanks for
34 | all the suggestions and the support! Together we can make a resource
35 | beneficial to each and every Ruby developer out there.
36 |
37 | By the way, if you're into Rails you might want to check out the
38 | complementary
39 | [Ruby on Rails 3 Style Guide](https://github.com/bbatsov/rails-style-guide).
40 |
41 | # The Ruby Style Guide
42 |
43 | This Ruby style guide recommends best practices so that real-world Ruby
44 | programmers can write code that can be maintained by other real-world Ruby
45 | programmers. A style guide that reflects real-world usage gets used, and a
46 | style guide that holds to an ideal that has been rejected by the people it is
47 | supposed to help risks not getting used at all – no matter how good it is.
48 |
49 | The guide is separated into several sections of related rules. I've
50 | tried to add the rationale behind the rules (if it's omitted I've
51 | assumed that is pretty obvious).
52 |
53 | I didn't come up with all the rules out of nowhere - they are mostly
54 | based on my extensive career as a professional software engineer,
55 | feedback and suggestions from members of the Ruby community and
56 | various highly regarded Ruby programming resources, such as
57 | ["Programming Ruby 1.9"](http://pragprog.com/book/ruby3/programming-ruby-1-9)
58 | and ["The Ruby Programming Language"](http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177).
59 |
60 | The guide is still a work in progress - some rules are lacking
61 | examples, some rules don't have examples that illustrate them clearly
62 | enough. In due time these issues will be addressed - just keep them in
63 | mind for now.
64 |
65 | You can generate a PDF or an HTML copy of this guide using
66 | [Transmuter](https://github.com/TechnoGate/transmuter).
67 |
68 | ## Source Code Layout
69 |
70 | > Nearly everybody is convinced that every style but their own is
71 | > ugly and unreadable. Leave out the "but their own" and they're
72 | > probably right...
73 | > -- Jerry Coffin (on indentation)
74 |
75 | * Use `UTF-8` as the source file encoding.
76 | * Use two **spaces** per indentation level.
77 |
78 | ```Ruby
79 | # good
80 | def some_method
81 | do_something
82 | end
83 |
84 | # bad - four spaces
85 | def some_method
86 | do_something
87 | end
88 | ```
89 |
90 | * Use Unix-style line endings. (*BSD/Solaris/Linux/OSX users are covered by default,
91 | Windows users have to be extra careful.)
92 | * If you're using Git you might want to add the following
93 | configuration setting to protect your project from Windows line
94 | endings creeping in:
95 |
96 | ```Shell
97 | $ git config --global core.autocrlf true
98 | ```
99 |
100 | * Use spaces around operators, after commas, colons and semicolons, around `{`
101 | and before `}`. Whitespace might be (mostly) irrelevant to the Ruby
102 | interpreter, but its proper use is the key to writing easily
103 | readable code.
104 |
105 | ```Ruby
106 | sum = 1 + 2
107 | a, b = 1, 2
108 | 1 > 2 ? true : false; puts 'Hi'
109 | [1, 2, 3].each { |e| puts e }
110 | ```
111 |
112 | The only exception is when using the exponent operator:
113 |
114 | ```Ruby
115 | # bad
116 | e = M * c ** 2
117 |
118 | # good
119 | e = M * c**2
120 | ```
121 |
122 | * No spaces after `(`, `[` or before `]`, `)`.
123 |
124 | ```Ruby
125 | some(arg).other
126 | [1, 2, 3].length
127 | ```
128 |
129 | * Indent `when` as deep as `case`. I know that many would disagree
130 | with this one, but it's the style established in both the "The Ruby
131 | Programming Language" and "Programming Ruby".
132 |
133 | ```Ruby
134 | case
135 | when song.name == 'Misty'
136 | puts 'Not again!'
137 | when song.duration > 120
138 | puts 'Too long!'
139 | when Time.now.hour > 21
140 | puts "It's too late"
141 | else
142 | song.play
143 | end
144 |
145 | kind = case year
146 | when 1850..1889 then 'Blues'
147 | when 1890..1909 then 'Ragtime'
148 | when 1910..1929 then 'New Orleans Jazz'
149 | when 1930..1939 then 'Swing'
150 | when 1940..1950 then 'Bebop'
151 | else 'Jazz'
152 | end
153 | ```
154 |
155 | * Use empty lines between `def`s and to break up a method into logical
156 | paragraphs.
157 |
158 | ```Ruby
159 | def some_method
160 | data = initialize(options)
161 |
162 | data.manipulate!
163 |
164 | data.result
165 | end
166 |
167 | def some_method
168 | result
169 | end
170 | ```
171 |
172 | * Indent the parameters of a method call with two spaces if they span over multiple lines.
173 | Optionally place the trailing `)` on its own line returning to the parent indentation.
174 |
175 | ```Ruby
176 | # starting point (line is too long)
177 | def send_mail(source)
178 | Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
179 | end
180 |
181 | # bad (large indent aligning with the method's open-parenthesis)
182 | def send_mail(source)
183 | Mailer.deliver(to: 'bob@example.com',
184 | from: 'us@example.com',
185 | subject: 'Important message',
186 | body: source.text)
187 | end
188 |
189 | # bad (double indent)
190 | def send_mail(source)
191 | Mailer.deliver(
192 | to: 'bob@example.com',
193 | from: 'us@example.com',
194 | subject: 'Important message',
195 | body: source.text)
196 | end
197 |
198 | # good (two space indent)
199 | def send_mail(source)
200 | Mailer.deliver(
201 | to: 'bob@example.com',
202 | from: 'us@example.com',
203 | subject: 'Important message',
204 | body: source.text)
205 | end
206 |
207 | # good (two space indent with close parenthesis returning to parent indent)
208 | def send_mail(source)
209 | Mailer.deliver(
210 | to: 'bob@example.com',
211 | from: 'us@example.com',
212 | subject: 'Important message',
213 | body: source.text
214 | )
215 | end
216 | ```
217 |
218 | * Use RDoc and its conventions for API documentation. Don't put an
219 | empty line between the comment block and the `def`.
220 | * Keep lines fewer than 120 characters. This is how many github will show
221 | without scrolling to the right. 80 is a common recommendation, but some
222 | find this too limiting, which is fine - but 120 is the maximum.
223 |
224 | Note that this applies to ruby code, and where possible other files, but
225 | where not possible (such as cucumber features) this limitation may not apply.
226 |
227 | * Avoid trailing whitespace.
228 | * End files with a newline. It's good practice, and without it git complains with
229 |
230 | `\ No newline at end of file`
231 |
232 | ## Syntax
233 |
234 |
235 | ### For
236 |
237 | * Never use `for`, unless you know exactly why. Most of the time iterators
238 | should be used instead. `for` is implemented in terms of `each` (so
239 | you're adding a level of indirection), but with a twist - `for`
240 | doesn't introduce a new scope (unlike `each`) and variables defined
241 | in its block will be visible outside it.
242 |
243 | ```Ruby
244 | arr = [1, 2, 3]
245 |
246 | # bad
247 | for elem in arr do
248 | puts elem
249 | end
250 |
251 | # good
252 | arr.each { |elem| puts elem }
253 | ```
254 |
255 | ### Comparisons
256 |
257 | * Avoid comparing booleans to boolean constants.
258 |
259 | ```Ruby
260 | # bad
261 | if condition == true
262 |
263 | # good
264 | if condition
265 |
266 | # bad
267 | options[:verbose] = true
268 | puts "Loading…" unless options[:verbose] == false
269 |
270 | # good
271 | options[:silent] = false
272 | puts "Loading…" unless options[:silent]
273 | ```
274 |
275 | ### If blocks
276 |
277 | * Never use `then` for multi-line `if/unless`.
278 |
279 | ```Ruby
280 | # bad
281 | if some_condition then
282 | # body omitted
283 | end
284 |
285 | # good
286 | if some_condition
287 | # body omitted
288 | end
289 | ```
290 |
291 | * Favor the ternary operator(`?:`) over `if/then/else/end` constructs.
292 | It's more common and obviously more concise.
293 |
294 | ```Ruby
295 | # bad
296 | result = if some_condition then something else something_else end
297 |
298 | # good
299 | result = some_condition ? something : something_else
300 | ```
301 |
302 | * Use one expression per branch in a ternary operator. This
303 | also means that ternary operators must not be nested. Prefer
304 | `if/else` constructs in these cases.
305 |
306 | ```Ruby
307 | # bad
308 | some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
309 |
310 | # good
311 | if some_condition
312 | nested_condition ? nested_something : nested_something_else
313 | else
314 | something_else
315 | end
316 | ```
317 |
318 | * Never use `if x: ...` - it is removed in Ruby 1.9. Use
319 | the ternary operator instead.
320 |
321 | ```Ruby
322 | # bad
323 | result = if some_condition: something else something_else end
324 |
325 | # good
326 | result = some_condition ? something : something_else
327 | ```
328 |
329 | * Never use `if x; ...`. Use the ternary operator instead.
330 |
331 | * Use `when x then ...` for one-line cases. The alternative syntax
332 | `when x: ...` is removed in Ruby 1.9.
333 |
334 | * Never use `when x; ...`. See the previous rule.
335 |
336 | * Use `&&/||` for boolean expressions, `and/or` for control flow. (Rule
337 | of thumb: If you have to use outer parentheses, you are using the
338 | wrong operators.)
339 |
340 | ```Ruby
341 | # boolean expression
342 | if some_condition && some_other_condition
343 | do_something
344 | end
345 |
346 | # control flow
347 | document.saved? or document.save!
348 | ```
349 |
350 | * Avoid multi-line `?:` (the ternary operator), use `if/unless` instead.
351 |
352 | * Favor modifier `if/unless` usage when you have a single-line
353 | body. Another good alternative is the usage of control flow `and/or`.
354 |
355 | ```Ruby
356 | # bad
357 | if some_condition
358 | do_something
359 | end
360 |
361 | # good
362 | do_something if some_condition
363 |
364 | # another good option
365 | some_condition and do_something
366 | ```
367 |
368 | * Favor `unless` over `if` for negative conditions (or control
369 | flow `or`).
370 |
371 | ```Ruby
372 | # bad
373 | do_something if !some_condition
374 |
375 | # good
376 | do_something unless some_condition
377 |
378 | # another good option
379 | some_condition or do_something
380 | ```
381 |
382 | * Never use `unless` with `else`. Rewrite these with the positive case first.
383 |
384 | ```Ruby
385 | # bad
386 | unless success?
387 | puts 'failure'
388 | else
389 | puts 'success'
390 | end
391 |
392 | # good
393 | if success?
394 | puts 'success'
395 | else
396 | puts 'failure'
397 | end
398 | ```
399 |
400 | * Don't use parentheses around the condition of an `if/unless/while`,
401 | unless the condition contains an assignment (see "Using the return
402 | value of `=`" below).
403 |
404 | ```Ruby
405 | # bad
406 | if (x > 10)
407 | # body omitted
408 | end
409 |
410 | # good
411 | if x > 10
412 | # body omitted
413 | end
414 |
415 | # ok
416 | if (x = self.next_value)
417 | # body omitted
418 | end
419 | ```
420 |
421 | ### Blocks
422 |
423 | * Prefer `{...}` over `do...end` for single-line blocks. Avoid using
424 | `{...}` for multi-line blocks (multiline chaining is always
425 | ugly). Always use `do...end` for "control flow" and "method
426 | definitions" (e.g. in Rakefiles and certain DSLs). Avoid `do...end`
427 | when chaining.
428 |
429 | ```Ruby
430 | names = ["Bozhidar", "Steve", "Sarah"]
431 |
432 | # good
433 | names.each { |name| puts name }
434 |
435 | # bad
436 | names.each do |name|
437 | puts name
438 | end
439 |
440 | # good
441 | names.select { |name| name.start_with?("S") }.map { |name| name.upcase }
442 |
443 | # bad
444 | names.select do |name|
445 | name.start_with?("S")
446 | end.map { |name| name.upcase }
447 | ```
448 |
449 | Some will argue that multiline chaining would look OK with the use of `{...}`, but they should
450 | ask themselves: Is this code really readable, and could the block contents be extracted into
451 | nifty methods?
452 |
453 | * Use the new lambda literal syntax.
454 |
455 | ```Ruby
456 | # bad
457 | lambda = lambda { |a, b| a + b }
458 | lambda.call(1, 2)
459 |
460 | # good
461 | lambda = ->(a, b) { a + b }
462 | lambda.(1, 2)
463 | ```
464 |
465 | * Use `_` for unused block parameters.
466 |
467 | ```Ruby
468 | # bad
469 | result = hash.map { |k, v| v + 1 }
470 |
471 | # good
472 | result = hash.map { |_, v| v + 1 }
473 | ```
474 |
475 | ### Methods
476 |
477 | * Use `def` with parentheses when there are arguments. Omit the
478 | parentheses when the method doesn't accept any arguments.
479 |
480 | ```Ruby
481 | def some_method
482 | # body omitted
483 | end
484 |
485 | def some_method_with_arguments(arg1, arg2)
486 | # body omitted
487 | end
488 | ```
489 |
490 | * Omit parentheses around parameters for methods that are part of an
491 | internal DSL (e.g. Rake, Rails, RSpec), methods that are with
492 | "keyword" status in Ruby (e.g. `attr_reader`, `puts`) and attribute
493 | access methods. Use parentheses around the arguments of all other
494 | method invocations.
495 |
496 | ```Ruby
497 | class Person
498 | attr_reader :name, :age
499 |
500 | # omitted
501 | end
502 |
503 | temperance = Person.new('Temperance', 30)
504 | temperance.name
505 |
506 | puts temperance.age
507 |
508 | x = Math.sin(y)
509 | array.delete(e)
510 | ```
511 |
512 | * Avoid `return` where not required.
513 |
514 | ```Ruby
515 | # bad
516 | def some_method(some_arr)
517 | return some_arr.size
518 | end
519 |
520 | # good
521 | def some_method(some_arr)
522 | some_arr.size
523 | end
524 | ```
525 |
526 | * Use spaces around the `=` operator when assigning default values to method parameters:
527 |
528 | ```Ruby
529 | # bad
530 | def some_method(arg1=:default, arg2=nil, arg3=[])
531 | # do something...
532 | end
533 |
534 | # good
535 | def some_method(arg1 = :default, arg2 = nil, arg3 = [])
536 | # do something...
537 | end
538 | ```
539 |
540 | While several Ruby books suggest the first style, the second is much more prominent
541 | in practice (and arguably a bit more readable).
542 |
543 | * Never put a space between a method name and the opening parenthesis.
544 |
545 | ```Ruby
546 | # bad
547 | f (3 + 2) + 1
548 |
549 | # good
550 | f(3 + 2) + 1
551 | ```
552 |
553 | * If the first argument to a method begins with an open parenthesis,
554 | always use parentheses in the method invocation. For example, write
555 | `f((3 + 2) + 1)`.
556 |
557 | * Always run the Ruby interpreter with the `-w` option so it will warn
558 | you if you forget either of the rules above!
559 |
560 |
561 | ### Assignments
562 |
563 | * Avoid line continuation (\\) where not required. In practice, avoid using
564 | line continuations at all.
565 |
566 | ```Ruby
567 | # bad
568 | result = 1 - \
569 | 2
570 |
571 | # good (but still ugly as hell)
572 | result = 1 \
573 | - 2
574 | ```
575 |
576 | * Using the return value of `=` (an assignment) is ok, but surround the
577 | assignment with parenthesis.
578 |
579 | ```Ruby
580 | # good - shows intented use of assignment
581 | if (v = array.grep(/foo/)) ...
582 |
583 | # bad
584 | if v = array.grep(/foo/) ...
585 |
586 | # also good - shows intended use of assignment and has correct precedence.
587 | if (v = self.next_value) == "hello" ...
588 | ```
589 |
590 | * Use `||=` freely to initialize variables.
591 |
592 | ```Ruby
593 | # set name to Bozhidar, only if it's nil or false
594 | name ||= 'Bozhidar'
595 | ```
596 |
597 | * Don't use `||=` to initialize boolean variables. (Consider what
598 | would happen if the current value happened to be `false`.)
599 |
600 | ```Ruby
601 | # bad - would set enabled to true even if it was false
602 | enabled ||= true
603 |
604 | # good
605 | enabled = true if enabled.nil?
606 | ```
607 |
608 | * Avoid using Perl-style special variables (like `$0-9`, `$``,
609 | etc. ). They are quite cryptic and their use in anything but
610 | one-liner scripts is discouraged.
611 |
612 | * When the keys of your hash are symbols use the Ruby 1.9 hash literal
613 | syntax.
614 |
615 | ```Ruby
616 | # bad
617 | hash = { :one => 1, :two => 2 }
618 |
619 | # good
620 | hash = { one: 1, two: 2 }
621 | ```
622 |
623 | ## Naming
624 |
625 | > The only real difficulties in programming are cache invalidation and
626 | > naming things.
627 | > -- Phil Karlton
628 |
629 | * Use `snake_case` for methods and variables.
630 | * Use `CamelCase` for classes and modules. (Keep acronyms like HTTP,
631 | RFC, XML uppercase.)
632 | * Use `SCREAMING_SNAKE_CASE` for other constants.
633 | * The names of predicate methods (methods that return a boolean value)
634 | should end in a question mark.
635 | (i.e. `Array#empty?`).
636 | * The names of potentially "dangerous" methods (i.e. methods that modify `self` or the
637 | arguments, `exit!`, etc.) should end with an exclamation mark.
638 | * When using `reduce` with short blocks, name the arguments `|a, e|`
639 | (accumulator, element).
640 | * When defining binary operators, name the argument `other`.
641 |
642 | ```Ruby
643 | def +(other)
644 | # body omitted
645 | end
646 | ```
647 |
648 | * Prefer `map` over `collect`, `find` over `detect`, `select` over
649 | `find_all`, `reduce` over `inject` and `size` over `length`. This is
650 | not a hard requirement; if the use of the alias enhances
651 | readability, it's ok to use it. The rhyming methods are inherited from
652 | Smalltalk and are not common in other programming languages. The
653 | reason the use of `select` is encouraged over `find_all` is that it
654 | goes together nicely with `reject` and its name is pretty self-explanatory.
655 |
656 | ## Comments
657 |
658 | > Good code is its own best documentation. As you're about to add a
659 | > comment, ask yourself, "How can I improve the code so that this
660 | > comment isn't needed?" Improve the code and then document it to make
661 | > it even clearer.
662 | > -- Steve McConnell
663 |
664 | * Write self-documenting code and ignore the rest of this section. Seriously!
665 | * Comments longer than a word are capitalized and use punctuation. Use [one
666 | space](http://en.wikipedia.org/wiki/Sentence_spacing) after periods.
667 | * Avoid superfluous comments.
668 |
669 | ```Ruby
670 | # bad
671 | counter += 1 # increments counter by one
672 | ```
673 |
674 | * Keep existing comments up-to-date. No comment is better than an outdated
675 | comment.
676 | * Avoid writing comments to explain bad code. Refactor the code to
677 | make it self-explanatory. (Do or do not - there is no try.)
678 |
679 | ## Annotations
680 |
681 | * Annotations should usually be written on the line immediately above
682 | the relevant code.
683 | * The annotation keyword is followed by a colon and a space, then a note
684 | describing the problem.
685 | * If multiple lines are required to describe the problem, subsequent
686 | lines should be indented two spaces after the `#`.
687 |
688 | ```Ruby
689 | def bar
690 | # FIXME: This has crashed occasionally since v3.2.1. It may
691 | # be related to the BarBazUtil upgrade.
692 | baz(:quux)
693 | end
694 | ```
695 |
696 | * In cases where the problem is so obvious that any documentation would
697 | be redundant, annotations may be left at the end of the offending line
698 | with no note. This usage should be the exception and not the rule.
699 |
700 | ```Ruby
701 | def bar
702 | sleep 100 # OPTIMIZE
703 | end
704 | ```
705 |
706 | * Use `TODO` to note missing features or functionality that should be
707 | added at a later date.
708 | * Use `FIXME` to note broken code that needs to be fixed.
709 | * Use `OPTIMIZE` to note slow or inefficient code that may cause
710 | performance problems.
711 | * Use `HACK` to note code smells where questionable coding practices
712 | were used and should be refactored away.
713 | * Use `REVIEW` to note anything that should be looked at to confirm it
714 | is working as intended. For example: `REVIEW: Are we sure this is how the
715 | client does X currently?`
716 | * Use other custom annotation keywords if it feels appropriate, but be
717 | sure to document them in your project's `README` or similar.
718 |
719 | ## Classes
720 |
721 | * When designing class hierarchies make sure that they conform to the
722 | [Liskov Substitution Principle](http://en.wikipedia.org/wiki/Liskov_substitution_principle).
723 | * Try to make your classes as
724 | [SOLID](http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29)
725 | as possible.
726 | * Always supply a proper `to_s` method for classes that represent
727 | domain objects.
728 |
729 | ```Ruby
730 | class Person
731 | attr_reader :first_name, :last_name
732 |
733 | def initialize(first_name, last_name)
734 | @first_name = first_name
735 | @last_name = last_name
736 | end
737 |
738 | def to_s
739 | "#@first_name #@last_name"
740 | end
741 | end
742 | ```
743 |
744 | * Use the `attr` family of functions to define trivial accessors or
745 | mutators.
746 |
747 | ```Ruby
748 | # bad
749 | class Person
750 | def initialize(first_name, last_name)
751 | @first_name = first_name
752 | @last_name = last_name
753 | end
754 |
755 | def first_name
756 | @first_name
757 | end
758 |
759 | def last_name
760 | @last_name
761 | end
762 | end
763 |
764 | # good
765 | class Person
766 | attr_reader :first_name, :last_name
767 |
768 | def initialize(first_name, last_name)
769 | @first_name = first_name
770 | @last_name = last_name
771 | end
772 | end
773 | ```
774 |
775 | * Consider adding factory methods to provide additional sensible ways
776 | to create instances of a particular class.
777 |
778 | ```Ruby
779 | class Person
780 | def self.create(options_hash)
781 | # body omitted
782 | end
783 | end
784 | ```
785 |
786 | * Prefer [duck-typing](http://en.wikipedia.org/wiki/Duck_typing) over inheritance.
787 |
788 | ```Ruby
789 | # bad
790 | class Animal
791 | # abstract method
792 | def speak
793 | end
794 | end
795 |
796 | # extend superclass
797 | class Duck < Animal
798 | def speak
799 | puts 'Quack! Quack'
800 | end
801 | end
802 |
803 | # extend superclass
804 | class Dog < Animal
805 | def speak
806 | puts 'Bau! Bau!'
807 | end
808 | end
809 |
810 | # good
811 | class Duck
812 | def speak
813 | puts 'Quack! Quack'
814 | end
815 | end
816 |
817 | class Dog
818 | def speak
819 | puts 'Bau! Bau!'
820 | end
821 | end
822 | ```
823 |
824 | * Avoid the usage of class (`@@`) variables due to their "nasty" behavior
825 | in inheritance.
826 |
827 | ```Ruby
828 | class Parent
829 | @@class_var = 'parent'
830 |
831 | def self.print_class_var
832 | puts @@class_var
833 | end
834 | end
835 |
836 | class Child < Parent
837 | @@class_var = 'child'
838 | end
839 |
840 | Parent.print_class_var # => will print "child"
841 | ```
842 |
843 | As you can see all the classes in a class hierarchy actually share one
844 | class variable. Class instance variables should usually be preferred
845 | over class variables.
846 |
847 | * Assign proper visibility levels to methods (`private`, `protected`)
848 | in accordance with their intended usage. Don't go off leaving
849 | everything `public` (which is the default). After all we're coding
850 | in *Ruby* now, not in *Python*.
851 | * Indent the `public`, `protected`, and `private` methods as much the
852 | method definitions they apply to. Leave one blank line above them.
853 |
854 | ```Ruby
855 | class SomeClass
856 | def public_method
857 | # ...
858 | end
859 |
860 | private
861 | def private_method
862 | # ...
863 | end
864 | end
865 | ```
866 |
867 | * Use `def self.method` to define singleton methods. This makes the methods
868 | more resistant to refactoring changes.
869 |
870 | ```Ruby
871 | class TestClass
872 | # bad
873 | def TestClass.some_method
874 | # body omitted
875 | end
876 |
877 | # good
878 | def self.some_other_method
879 | # body omitted
880 | end
881 |
882 | # Also possible and convenient when you
883 | # have to define many singleton methods.
884 | class << self
885 | def first_method
886 | # body omitted
887 | end
888 |
889 | def second_method_etc
890 | # body omitted
891 | end
892 | end
893 | end
894 | ```
895 |
896 | ## Exceptions
897 |
898 | * Don't suppress exceptions.
899 |
900 | ```Ruby
901 | begin
902 | # an exception occurs here
903 | rescue SomeError
904 | # the rescue clause does absolutely nothing
905 | end
906 | ```
907 |
908 | * Don't use exceptions for flow of control.
909 |
910 | ```Ruby
911 | # bad
912 | begin
913 | n / d
914 | rescue ZeroDivisionError
915 | puts "Cannot divide by 0!"
916 | end
917 |
918 | # good
919 | if n.zero?
920 | puts "Cannot divide by 0!"
921 | else
922 | n / d
923 | ```
924 |
925 | * Avoid rescuing the `Exception` class.
926 |
927 | ```Ruby
928 | # bad
929 | begin
930 | # an exception occurs here
931 | rescue
932 | # exception handling
933 | end
934 |
935 | # still bad
936 | begin
937 | # an exception occurs here
938 | rescue Exception
939 | # exception handling
940 | end
941 | ```
942 |
943 | * Put more specific exceptions higher up the rescue chain, otherwise
944 | they'll never be rescued from.
945 |
946 | ```Ruby
947 | # bad
948 | begin
949 | # some code
950 | rescue Exception => e
951 | # some handling
952 | rescue StandardError => e
953 | # some handling
954 | end
955 |
956 | # good
957 | begin
958 | # some code
959 | rescue StandardError => e
960 | # some handling
961 | rescue Exception => e
962 | # some handling
963 | end
964 | ```
965 |
966 | * Release external resources obtained by your program in an ensure
967 | block.
968 |
969 | ```Ruby
970 | f = File.open("testfile")
971 | begin
972 | # .. process
973 | rescue
974 | # .. handle error
975 | ensure
976 | f.close unless f.nil?
977 | end
978 | ```
979 |
980 | * Favor the use of exceptions for the standard library over
981 | introducing new exception classes.
982 |
983 | ## Collections
984 |
985 | * Prefer `%w` to the literal array syntax when you need an array of
986 | strings.
987 |
988 | ```Ruby
989 | # bad
990 | STATES = ['draft', 'open', 'closed']
991 |
992 | # good
993 | STATES = %w(draft open closed)
994 | ```
995 |
996 | * Avoid the creation of huge gaps in arrays.
997 |
998 | ```Ruby
999 | arr = []
1000 | arr[100] = 1 # now you have an array with lots of nils
1001 | ```
1002 |
1003 | * Use `Set` instead of `Array` when dealing with unique elements. `Set`
1004 | implements a collection of unordered values with no duplicates. This
1005 | is a hybrid of `Array`'s intuitive inter-operation facilities and
1006 | `Hash`'s fast lookup.
1007 | * Use symbols instead of strings as hash keys.
1008 |
1009 | ```Ruby
1010 | # bad
1011 | hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
1012 |
1013 | # good
1014 | hash = { one: 1, two: 2, three: 3 }
1015 | ```
1016 |
1017 | * Avoid the use of mutable object as hash keys.
1018 | * Use the new 1.9 literal hash syntax in preference to the hashrocket
1019 | syntax.
1020 |
1021 | ```Ruby
1022 | # bad
1023 | hash = { :one => 1, :two => 2, :three => 3 }
1024 |
1025 | # good
1026 | hash = { one: 1, two: 2, three: 3 }
1027 | ```
1028 |
1029 | * Rely on the fact that hashes in 1.9 are ordered.
1030 | * Never modify a collection while traversing it.
1031 |
1032 | ## Strings
1033 |
1034 | * Prefer string interpolation instead of string concatenation:
1035 |
1036 | ```Ruby
1037 | # bad
1038 | email_with_name = user.name + ' <' + user.email + '>'
1039 |
1040 | # good
1041 | email_with_name = "#{user.name} <#{user.email}>"
1042 | ```
1043 |
1044 | * Prefer single-quoted strings when you don't need string interpolation or
1045 | special symbols such as `\t`, `\n`, `'`, etc.
1046 |
1047 | ```Ruby
1048 | # bad
1049 | name = "Bozhidar"
1050 |
1051 | # good
1052 | name = 'Bozhidar'
1053 | ```
1054 |
1055 | * Don't use `{}` around instance variables being interpolated into a
1056 | string.
1057 |
1058 | ```Ruby
1059 | class Person
1060 | attr_reader :first_name, :last_name
1061 |
1062 | def initialize(first_name, last_name)
1063 | @first_name = first_name
1064 | @last_name = last_name
1065 | end
1066 |
1067 | # bad
1068 | def to_s
1069 | "#{@first_name} #{@last_name}"
1070 | end
1071 |
1072 | # good
1073 | def to_s
1074 | "#@first_name #@last_name"
1075 | end
1076 | end
1077 | ```
1078 |
1079 | * Avoid using `String#+` when you need to construct large data chunks.
1080 | Instead, use `String#<<`. Concatenation mutates the string instance in-place
1081 | and is always faster than `String#+`, which creates a bunch of new string objects.
1082 |
1083 | ```Ruby
1084 | # good and also fast
1085 | html = ''
1086 | html << '
#{paragraph}
" 1090 | end 1091 | ``` 1092 | 1093 | ## Regular Expressions 1094 | 1095 | * Don't use regular expressions if you just need plain text search in string: 1096 | `string['text']` 1097 | * For simple constructions you can use regexp directly through string index. 1098 | 1099 | ```Ruby 1100 | match = string[/regexp/] # get content of matched regexp 1101 | first_group = string[/text(grp)/, 1] # get content of captured group 1102 | string[/text (grp)/, 1] = 'replace' # string => 'text replace' 1103 | ``` 1104 | 1105 | * Use non capturing groups when you don't use captured result of parenthesis. 1106 | 1107 | ```Ruby 1108 | /(first|second)/ # bad 1109 | /(?:first|second)/ # good 1110 | ``` 1111 | 1112 | * Avoid using $1-9 as it can be hard to track what they contain. Named groups 1113 | can be used instead. 1114 | 1115 | ```Ruby 1116 | # bad 1117 | /(regexp)/ =~ string 1118 | ... 1119 | process $1 1120 | 1121 | # good 1122 | /(?