diff --git a/README.md b/README.md index 411fda25b..1fd94d36f 100644 --- a/README.md +++ b/README.md @@ -103,11 +103,11 @@ Translations of the guide are available in the following languages: * Use `UTF-8` as the source file encoding. -[[link](#utf-8)] + * Use two **spaces** per indentation level (aka soft tabs). No hard tabs. -[[link](#spaces-indentation)] + ```Ruby # bad - four spaces @@ -124,7 +124,7 @@ Translations of the guide are available in the following languages: * Use Unix-style line endings. (*BSD/Solaris/Linux/OS X users are covered by default, Windows users have to be extra careful.) -[[link](#crlf)] + * If you're using Git you might want to add the following configuration setting to protect your project from Windows line @@ -137,7 +137,7 @@ Translations of the guide are available in the following languages: * Don't use `;` to separate statements and expressions. As a corollary - use one expression per line. -[[link](#no-semicolon)] + ```Ruby # bad @@ -156,7 +156,7 @@ Translations of the guide are available in the following languages: * Prefer a single-line format for class definitions with no body. -[[link](#single-line-classes)] + ```Ruby # bad @@ -175,7 +175,7 @@ Translations of the guide are available in the following languages: there are a few peculiarities about their definition syntax that make their use undesirable. At any rate - there should be no more than one expression in a single-line method. -[[link](#no-single-line-methods)] + ```Ruby # bad @@ -207,7 +207,7 @@ Translations of the guide are available in the following languages: Use spaces around operators, after commas, colons and semicolons, around `{` and before `}`. Whitespace might be (mostly) irrelevant to the Ruby interpreter, but its proper use is the key to writing easily readable code. -[[link](#spaces-operators)] + ```Ruby sum = 1 + 2 @@ -245,7 +245,7 @@ Translations of the guide are available in the following languages: * No spaces after `(`, `[` or before `]`, `)`. -[[link](#no-spaces-braces)] + ```Ruby some(arg).other @@ -254,7 +254,7 @@ Translations of the guide are available in the following languages: * No space after `!`. -[[link](#no-space-bang)] + ```Ruby # bad @@ -266,7 +266,7 @@ Translations of the guide are available in the following languages: * No space inside range literals. -[[link](#no-space-inside-range-literals)] + ```Ruby # bad @@ -282,7 +282,7 @@ Translations of the guide are available in the following languages: Indent `when` as deep as `case`. I know that many would disagree with this one, but it's the style established in both "The Ruby Programming Language" and "Programming Ruby". -[[link](#indent-when-to-case)] + ```Ruby # bad @@ -313,7 +313,7 @@ Translations of the guide are available in the following languages: * When assigning the result of a conditional expression to a variable, preserve the usual alignment of its branches. -[[link](#indent-conditional-assignment)] + ```Ruby # bad - pretty convoluted @@ -370,7 +370,7 @@ Translations of the guide are available in the following languages: * Use empty lines between method definitions and also to break up a method into logical paragraphs internally. -[[link](#empty-lines-between-methods)] + ```Ruby def some_method @@ -389,7 +389,7 @@ Translations of the guide are available in the following languages: * Avoid comma after the last parameter in a method call, especially when the parameters are not on separate lines. -[[link](#no-trailing-params-comma)] + ```Ruby # bad - easier to move/add/remove parameters, but still not preferred @@ -409,7 +409,7 @@ Translations of the guide are available in the following languages: * Use spaces around the `=` operator when assigning default values to method parameters: -[[link](#spaces-around-equals)] + ```Ruby # bad @@ -429,7 +429,7 @@ Translations of the guide are available in the following languages: * Avoid line continuation `\` where not required. In practice, avoid using line continuations for anything but string concatenation. -[[link](#no-trailing-backslash)] + ```Ruby # bad @@ -448,7 +448,7 @@ Translations of the guide are available in the following languages: Adopt a consistent multi-line method chaining style. There are two popular styles in the Ruby community, both of which are considered good - leading `.` (Option A) and trailing `.` (Option B). -[[link](#consistent-multi-line-chains)] + * **(Option A)** When continuing a chained method invocation on another line keep the `.` on the second line. @@ -485,7 +485,7 @@ Translations of the guide are available in the following languages: line. When aligning parameters is not appropriate due to line-length constraints, single indent for the lines after the first is also acceptable. -[[link](#no-double-indent)] + ```Ruby # starting point (line is too long) @@ -523,7 +523,7 @@ Translations of the guide are available in the following languages: * Align the elements of array literals spanning multiple lines. -[[link](#align-multiline-arrays)] + ```Ruby # bad - single indent @@ -544,7 +544,7 @@ Translations of the guide are available in the following languages: * Add underscores to large numeric literals to improve their readability. -[[link](#underscores-in-numerics)] + ```Ruby # bad - how many 0s are there? @@ -557,24 +557,24 @@ Translations of the guide are available in the following languages: * Use RDoc and its conventions for API documentation. Don't put an empty line between the comment block and the `def`. -[[link](#rdoc-conventions)] + * Limit lines to 80 characters. -[[link](#80-character-limits)] + * Avoid trailing whitespace. -[[link](#no-trailing-whitespace)] + * End each file with a newline. -[[link](#newline-eof)] + * Don't use block comments. They cannot be preceded by whitespace and are not as easy to spot as regular comments. -[[link](#no-block-comments)] + ```Ruby # bad @@ -594,7 +594,7 @@ Translations of the guide are available in the following languages: Use `::` only to reference constants(this includes classes and modules) and constructors (like `Array()` or `Nokogiri::HTML()`). Do not use `::` for regular method invocation. -[[link](#double-colons)] + ```Ruby # bad @@ -611,7 +611,7 @@ Translations of the guide are available in the following languages: * Use `def` with parentheses when there are parameters. Omit the parentheses when the method doesn't accept any parameters. -[[link](#method-parens)] + ```Ruby # bad @@ -641,7 +641,7 @@ Translations of the guide are available in the following languages: the splat operator, or when used to swap variable assignment. Parallel assignment is less readable than separate assignment. It is also slightly slower than separate assignment. -[[link](#parallel-assignment)] + ```Ruby # bad @@ -684,7 +684,7 @@ Translations of the guide are available in the following languages: you're adding a level of indirection), but with a twist - `for` doesn't introduce a new scope (unlike `each`) and variables defined in its block will be visible outside it. -[[link](#no-for-loops)] + ```Ruby arr = [1, 2, 3] @@ -706,7 +706,7 @@ Translations of the guide are available in the following languages: * Do not use `then` for multi-line `if/unless`. -[[link](#no-then)] + ```Ruby # bad @@ -723,7 +723,7 @@ Translations of the guide are available in the following languages: * Always put the condition on the same line as the `if`/`unless` in a multi-line conditional. -[[link](#same-line-condition)] + ```Ruby # bad @@ -743,7 +743,7 @@ Translations of the guide are available in the following languages: * Favor the ternary operator(`?:`) over `if/then/else/end` constructs. It's more common and obviously more concise. -[[link](#ternary-operator)] + ```Ruby # bad @@ -757,7 +757,7 @@ Translations of the guide are available in the following languages: Use one expression per branch in a ternary operator. This also means that ternary operators must not be nested. Prefer `if/else` constructs in these cases. -[[link](#no-nested-ternary)] + ```Ruby # bad @@ -774,7 +774,7 @@ Translations of the guide are available in the following languages: * Do not use `if x; ...`. Use the ternary operator instead. -[[link](#no-semicolon-ifs)] + ```Ruby # bad @@ -787,7 +787,7 @@ Translations of the guide are available in the following languages: * Leverage the fact that `if` and `case` are expressions which return a result. -[[link](#use-if-case-returns)] + ```Ruby # bad @@ -809,15 +809,15 @@ Translations of the guide are available in the following languages: * Use `when x then ...` for one-line cases. The alternative syntax `when x: ...` has been removed as of Ruby 1.9. -[[link](#one-line-cases)] + * Do not use `when x; ...`. See the previous rule. -[[link](#no-when-semicolons)] + * Use `!` instead of `not`. -[[link](#bang-not-not)] + ```Ruby # bad - braces are required because of op precedence @@ -829,7 +829,7 @@ Translations of the guide are available in the following languages: * Avoid the use of `!!`. -[[link](#no-bang-bang)] + ```Ruby # bad @@ -853,7 +853,7 @@ Translations of the guide are available in the following languages: * The `and` and `or` keywords are banned. It's just not worth it. Always use `&&` and `||` instead. -[[link](#no-and-or-or)] + ```Ruby # bad @@ -877,12 +877,12 @@ Translations of the guide are available in the following languages: * Avoid multi-line `?:` (the ternary operator); use `if/unless` instead. -[[link](#no-multiline-ternary)] + * Favor modifier `if/unless` usage when you have a single-line body. Another good alternative is the usage of control flow `&&/||`. -[[link](#if-as-a-modifier)] + ```Ruby # bad @@ -900,7 +900,7 @@ Translations of the guide are available in the following languages: * Avoid modifier `if/unless` usage at the end of a non-trivial multi-line block. -[[link](#no-multiline-if-modifiers)] + ```Ruby # bad @@ -918,7 +918,7 @@ Translations of the guide are available in the following languages: * Favor `unless` over `if` for negative conditions (or control flow `||`). -[[link](#unless-for-negatives)] + ```Ruby # bad @@ -936,7 +936,7 @@ Translations of the guide are available in the following languages: * Do not use `unless` with `else`. Rewrite these with the positive case first. -[[link](#no-else-with-unless)] + ```Ruby # bad @@ -956,7 +956,7 @@ Translations of the guide are available in the following languages: * Don't use parentheses around the condition of an `if/unless/while/until`. -[[link](#no-parens-if)] + ```Ruby # bad @@ -975,7 +975,7 @@ condition](#safe-assignment-in-condition). * Do not use `while/until condition do` for multi-line `while/until`. -[[link](#no-multiline-while-do)] + ```Ruby # bad @@ -999,7 +999,7 @@ condition](#safe-assignment-in-condition). * Favor modifier `while/until` usage when you have a single-line body. -[[link](#while-as-a-modifier)] + ```Ruby # bad @@ -1013,7 +1013,7 @@ condition](#safe-assignment-in-condition). * Favor `until` over `while` for negative conditions. -[[link](#until-for-negatives)] + ```Ruby # bad @@ -1025,7 +1025,7 @@ condition](#safe-assignment-in-condition). * Use `Kernel#loop` instead of `while/until` when you need an infinite loop. -[[link](#infinite-loop)] + ```ruby # bad @@ -1046,7 +1046,7 @@ condition](#safe-assignment-in-condition). * Use `Kernel#loop` with `break` rather than `begin/end/until` or `begin/end/while` for post-loop tests. -[[link](#loop-with-break)] + ```Ruby # bad @@ -1068,7 +1068,7 @@ condition](#safe-assignment-in-condition). DSL (e.g. Rake, Rails, RSpec), methods that have "keyword" status in Ruby (e.g. `attr_reader`, `puts`) and attribute access methods. Use parentheses around the arguments of all other method invocations. -[[link](#no-dsl-parens)] + ```Ruby class Person @@ -1090,7 +1090,7 @@ condition](#safe-assignment-in-condition). * Omit the outer braces around an implicit options hash. -[[link](#no-braces-opts-hash)] + ```Ruby # bad @@ -1103,7 +1103,7 @@ condition](#safe-assignment-in-condition). * Omit both the outer braces and parentheses for methods that are part of an internal DSL. -[[link](#no-dsl-decorating)] + ```Ruby class Person < ActiveRecord::Base @@ -1117,7 +1117,7 @@ condition](#safe-assignment-in-condition). * Omit parentheses for method calls with no arguments. -[[link](#no-args-no-parens)] + ```Ruby # bad @@ -1135,7 +1135,7 @@ condition](#safe-assignment-in-condition). * Use the proc invocation shorthand when the invoked method is the only operation of a block. -[[link](#single-action-blocks)] + ```Ruby # bad @@ -1150,7 +1150,7 @@ condition](#safe-assignment-in-condition). for multi-line blocks (multiline chaining is always ugly). Always use `do...end` for "control flow" and "method definitions" (e.g. in Rakefiles and certain DSLs). Avoid `do...end` when chaining. -[[link](#single-line-blocks)] + ```Ruby names = %w(Bozhidar Steve Sarah) @@ -1180,7 +1180,7 @@ condition](#safe-assignment-in-condition). Consider using explicit block argument to avoid writing block literal that just passes its arguments to another block. Beware of the performance impact, though, as the block gets converted to a Proc. -[[link](#block-argument)] + ```Ruby require 'tempfile' @@ -1206,7 +1206,7 @@ condition](#safe-assignment-in-condition). * Avoid `return` where not required for flow of control. -[[link](#no-explicit-return)] + ```Ruby # bad @@ -1223,7 +1223,7 @@ condition](#safe-assignment-in-condition). * Avoid `self` where not required. (It is only required when calling a self write accessor.) -[[link](#no-self-unless-required)] + ```Ruby # bad @@ -1248,7 +1248,7 @@ condition](#safe-assignment-in-condition). * As a corollary, avoid shadowing methods with local variables unless they are both equivalent. -[[link](#no-shadowing)] + ```Ruby class Foo @@ -1281,7 +1281,7 @@ condition](#safe-assignment-in-condition). unless the assignment is wrapped in parentheses. This is a fairly popular idiom among Rubyists that's sometimes referred to as *safe assignment in condition*. -[[link](#safe-assignment-in-condition)] + ```Ruby # bad (+ a warning) @@ -1306,7 +1306,7 @@ condition](#safe-assignment-in-condition). * Use shorthand self assignment operators whenever applicable. -[[link](#self-assignment)] + ```Ruby # bad @@ -1328,7 +1328,7 @@ condition](#safe-assignment-in-condition). * Use `||=` to initialize variables only if they're not already initialized. -[[link](#double-pipe-for-uninit)] + ```Ruby # bad @@ -1344,7 +1344,7 @@ condition](#safe-assignment-in-condition). * Don't use `||=` to initialize boolean variables. (Consider what would happen if the current value happened to be `false`.) -[[link](#no-double-pipes-for-bools)] + ```Ruby # bad - would set enabled to true even if it was false @@ -1358,7 +1358,7 @@ condition](#safe-assignment-in-condition). Use `&&=` to preprocess variables that may or may not exist. Using `&&=` will change the value only if it exists, removing the need to check its existence with `if`. -[[link](#double-amper-preprocess)] + ```Ruby # bad @@ -1383,7 +1383,7 @@ condition](#safe-assignment-in-condition). Avoid explicit use of the case equality operator `===`. As its name implies it is meant to be used implicitly by `case` expressions and outside of them it yields some pretty confusing code. -[[link](#no-case-equality)] + ```Ruby # bad @@ -1400,7 +1400,7 @@ condition](#safe-assignment-in-condition). * Do not use `eql?` when using `==` will do. The stricter comparison semantics provided by `eql?` are rarely needed in practice. -[[link](#eql)] + ```Ruby # bad - eql? is the same as == for strings @@ -1415,7 +1415,7 @@ condition](#safe-assignment-in-condition). Avoid using Perl-style special variables (like `$:`, `$;`, etc. ). They are quite cryptic and their use in anything but one-liner scripts is discouraged. Use the human-friendly aliases provided by the `English` library. -[[link](#no-cryptic-perlisms)] + ```Ruby # bad @@ -1428,7 +1428,7 @@ condition](#safe-assignment-in-condition). * Do not put a space between a method name and the opening parenthesis. -[[link](#parens-no-spaces)] + ```Ruby # bad @@ -1441,19 +1441,19 @@ condition](#safe-assignment-in-condition). * If the first argument to a method begins with an open parenthesis, always use parentheses in the method invocation. For example, write `f((3 + 2) + 1)`. -[[link](#parens-as-args)] + * Always run the Ruby interpreter with the `-w` option so it will warn you if you forget either of the rules above! -[[link](#always-warn-at-runtime)] + * Do not use nested method definitions, use lambda instead. Nested method definitions actually produce methods in the same scope (e.g. class) as the outer method. Furthermore, the "nested method" will be redefined every time the method containing its definition is invoked. -[[link](#no-nested-methods)] + ```Ruby # bad @@ -1484,7 +1484,7 @@ condition](#safe-assignment-in-condition). * Use the new lambda literal syntax for single line body blocks. Use the `lambda` method for multi-line blocks. -[[link](#lambda-multi-line)] + ```Ruby # bad @@ -1510,7 +1510,7 @@ condition](#safe-assignment-in-condition). * Don't omit the parameter parentheses when defining a stabby lambda with parameters. -[[link](#stabby-lambda-with-args)] + ```Ruby # bad @@ -1523,7 +1523,7 @@ parameters. * Omit the parameter parentheses when defining a stabby lambda with no parameters. -[[link](#stabby-lambda-no-args)] + ```Ruby # bad @@ -1535,7 +1535,7 @@ no parameters. * Prefer `proc` over `Proc.new`. -[[link](#proc)] + ```Ruby # bad @@ -1547,7 +1547,7 @@ no parameters. * Prefer `proc.call()` over `proc[]` or `proc.()` for both lambdas and procs. -[[link](#proc-call)] + ```Ruby # bad - looks similar to Enumeration access @@ -1568,7 +1568,7 @@ no parameters. acceptable to use just `_` (although it's a bit less descriptive). This convention is recognized by the Ruby interpreter and tools like RuboCop and will suppress their unused variable warnings. -[[link](#underscore-unused-vars)] + ```Ruby # bad @@ -1601,18 +1601,18 @@ no parameters. `STDOUT/STDERR/STDIN` are constants, and while you can actually reassign (possibly to redirect some stream) constants in Ruby, you'll get an interpreter warning if you do so. -[[link](#global-stdout)] + * Use `warn` instead of `$stderr.puts`. Apart from being more concise and clear, `warn` allows you to suppress warnings if you need to (by setting the warn level to 0 via `-W0`). -[[link](#warn)] + * Favor the use of `sprintf` and its alias `format` over the fairly cryptic `String#%` method. -[[link](#sprintf)] + ```Ruby # bad @@ -1637,7 +1637,7 @@ no parameters. * Favor the use of `Array#join` over the fairly cryptic `Array#*` with -[[link](#array-join)] + a string argument. ```Ruby @@ -1654,7 +1654,7 @@ no parameters. Use `[*var]` or `Array()` instead of explicit `Array` check, when dealing with a variable you want to treat as an Array, but you're not certain it's an array. -[[link](#splat-arrays)] + ```Ruby # bad @@ -1671,7 +1671,7 @@ no parameters. * Use ranges or `Comparable#between?` instead of complex comparison logic when possible. -[[link](#ranges-or-between)] + ```Ruby # bad @@ -1687,7 +1687,7 @@ no parameters. * Favor the use of predicate methods to explicit comparisons with `==`. Numeric comparisons are OK. -[[link](#predicate-methods)] + ```Ruby # bad @@ -1720,7 +1720,7 @@ no parameters. * Don't do explicit non-`nil` checks unless you're dealing with boolean values. -[[link](#no-non-nil-checks)] + ```ruby # bad @@ -1738,11 +1738,11 @@ no parameters. * Avoid the use of `BEGIN` blocks. -[[link](#no-BEGIN-blocks)] + * Do not use `END` blocks. Use `Kernel#at_exit` instead. -[[link](#no-END-blocks)] + ```ruby # bad @@ -1754,11 +1754,11 @@ no parameters. * Avoid the use of flip-flops. -[[link](#no-flip-flops)] + * Avoid use of nested conditionals for flow of control. -[[link](#no-nested-conditionals)] + Prefer a guard clause when you can assert invalid data. A guard clause is a conditional statement at the top of a function that bails out as @@ -1811,13 +1811,13 @@ no parameters. programming languages. The reason the use of `select` is encouraged over `find_all` is that it goes together nicely with `reject` and its name is pretty self-explanatory. -[[link](#map-find-select-reduce-size)] + * Don't use `count` as a substitute for `size`. For `Enumerable` objects other than `Array` it will iterate the entire collection in order to determine its size. -[[link](#count-vs-size)] + ```Ruby # bad @@ -1832,7 +1832,7 @@ no parameters. with a depth greater than 2, i.e. if `users.first.songs == ['a', ['b','c']]`, then use `map + flatten` rather than `flat_map`. `flat_map` flattens the array by 1, whereas `flatten` flattens it all the way. -[[link](#flat-map)] + ```Ruby # bad @@ -1848,7 +1848,7 @@ no parameters. where a class does not provide a specialized implementation, the general implementation inherited from `Enumerable` will be at least as efficient as using `reverse.each`. -[[link](#reverse-each)] + ```Ruby # bad @@ -1866,7 +1866,7 @@ no parameters. * Name identifiers in English. -[[link](#english-identifiers)] + ```Ruby # bad - identifier using non-ascii characters @@ -1881,7 +1881,7 @@ no parameters. * Use `snake_case` for symbols, methods and variables. -[[link](#snake-case-symbols-methods-vars)] + ```Ruby # bad @@ -1910,7 +1910,7 @@ no parameters. * Use `CamelCase` for classes and modules. (Keep acronyms like HTTP, RFC, XML uppercase.) -[[link](#camelcase-classes)] + ```Ruby # bad @@ -1946,21 +1946,21 @@ no parameters. * Use `snake_case` for naming files, e.g. `hello_world.rb`. -[[link](#snake-case-files)] + * Use `snake_case` for naming directories, e.g. `lib/hello_world/hello_world.rb`. -[[link](#snake-case-dirs)] + * Aim to have just a single class/module per source file. Name the file name as the class/module, but replacing CamelCase with snake_case. -[[link](#one-class-per-file)] + * Use `SCREAMING_SNAKE_CASE` for other constants. -[[link](#screaming-snake-case)] + ```Ruby # bad @@ -1974,14 +1974,14 @@ no parameters. The names of predicate methods (methods that return a boolean value) should end in a question mark. (i.e. `Array#empty?`). Methods that don't return a boolean, shouldn't end in a question mark. -[[link](#bool-methods-qmark)] + * The names of potentially *dangerous* methods (i.e. methods that modify `self` or the arguments, `exit!` (doesn't run the finalizers like `exit` does), etc.) should end with an exclamation mark if there exists a safe version of that *dangerous* method. -[[link](#dangerous-method-bang)] + ```Ruby # bad - there is no matching 'safe' method @@ -2009,7 +2009,7 @@ no parameters. * Define the non-bang (safe) method in terms of the bang (dangerous) one if possible. -[[link](#safe-because-unsafe)] + ```Ruby class Array @@ -2032,12 +2032,12 @@ no parameters. * When using `reduce` with short blocks, name the arguments `|a, e|` (accumulator, element). -[[link](#reduce-blocks)] + * When defining binary operators, name the parameter `other`(`<<` and `[]` are exceptions to the rule, since their semantics are different). -[[link](#other-arg)] + ```Ruby def +(other) @@ -2055,25 +2055,25 @@ no parameters. * Write self-documenting code and ignore the rest of this section. Seriously! -[[link](#no-comments)] + * Write comments in English. -[[link](#english-comments)] + * Use one space between the leading `#` character of the comment and the text of the comment. -[[link](#hash-space)] + * Comments longer than a word are capitalized and use punctuation. Use [one space](http://en.wikipedia.org/wiki/Sentence_spacing) after periods. -[[link](#english-syntax)] + * Avoid superfluous comments. -[[link](#no-superfluous-comments)] + ```Ruby # bad @@ -2083,7 +2083,7 @@ no parameters. * Keep existing comments up-to-date. An outdated comment is worse than no comment at all. -[[link](#comment-upkeep)] + > Good code is like a good joke - it needs no explanation.
> -- Russ Olsen @@ -2091,25 +2091,25 @@ no parameters. * Avoid writing comments to explain bad code. Refactor the code to make it self-explanatory. (Do or do not - there is no try. --Yoda) -[[link](#refactor-dont-comment)] + ### Comment Annotations * Annotations should usually be written on the line immediately above the relevant code. -[[link](#annotate-above)] + * The annotation keyword is followed by a colon and a space, then a note describing the problem. -[[link](#annotate-keywords)] + * If multiple lines are required to describe the problem, subsequent lines should be indented three spaces after the `#` (one general plus two for indentation purpose). -[[link](#indent-annotations)] + ```Ruby def bar @@ -2123,7 +2123,7 @@ no parameters. In cases where the problem is so obvious that any documentation would be redundant, annotations may be left at the end of the offending line with no note. This usage should be the exception and not the rule. -[[link](#rare-eol-annotations)] + ```Ruby def bar @@ -2134,38 +2134,38 @@ no parameters. * Use `TODO` to note missing features or functionality that should be added at a later date. -[[link](#todo)] + * Use `FIXME` to note broken code that needs to be fixed. -[[link](#fixme)] + * Use `OPTIMIZE` to note slow or inefficient code that may cause performance problems. -[[link](#optimize)] + * Use `HACK` to note code smells where questionable coding practices were used and should be refactored away. -[[link](#hack)] + * Use `REVIEW` to note anything that should be looked at to confirm it is working as intended. For example: `REVIEW: Are we sure this is how the client does X currently?` -[[link](#review)] + * Use other custom annotation keywords if it feels appropriate, but be sure to document them in your project's `README` or similar. -[[link](#document-annotations)] + ## Classes & Modules * Use a consistent structure in your class definitions. -[[link](#consistent-classes)] + ```Ruby class Person @@ -2213,7 +2213,7 @@ no parameters. * Don't nest multi line classes within classes. Try to have such nested classes each in their own file in a folder named like the containing class. -[[link](#file-classes)] + ```Ruby # bad @@ -2256,7 +2256,7 @@ no parameters. * Prefer modules to classes with only class methods. Classes should be used only when it makes sense to create instances out of them. -[[link](#modules-vs-classes)] + ```Ruby # bad @@ -2285,7 +2285,7 @@ no parameters. * Favor the use of `module_function` over `extend self` when you want to turn a module's instance methods into class methods. -[[link](#module-function)] + ```Ruby # bad @@ -2319,18 +2319,18 @@ no parameters. When designing class hierarchies make sure that they conform to the [Liskov Substitution Principle](http://en.wikipedia.org/wiki/Liskov_substitution_principle). -[[link](#liskov)] + * Try to make your classes as [SOLID](http://en.wikipedia.org/wiki/SOLID_\(object-oriented_design\)) as possible. -[[link](#solid-design)] + * Always supply a proper `to_s` method for classes that represent domain objects. -[[link](#define-to-s)] + ```Ruby class Person @@ -2349,7 +2349,7 @@ no parameters. * Use the `attr` family of functions to define trivial accessors or mutators. -[[link](#attr_family)] + ```Ruby # bad @@ -2381,7 +2381,7 @@ no parameters. * Avoid the use of `attr`. Use `attr_reader` and `attr_accessor` instead. -[[link](#attr)] + ```Ruby # bad - creates a single attribute accessor (deprecated in 1.9) @@ -2396,7 +2396,7 @@ no parameters. * Consider using `Struct.new`, which defines the trivial accessors, constructor and comparison operators for you. -[[link](#struct-new)] + ```Ruby # good @@ -2418,7 +2418,7 @@ no parameters. Don't extend an instance initialized by `Struct.new`. Extending it introduces a superfluous class level and may also introduce weird errors if the file is required multiple times. -[[link](#no-extend-struct-new)] + ```Ruby # bad @@ -2432,7 +2432,7 @@ no parameters. * Consider adding factory methods to provide additional sensible ways to create instances of a particular class. -[[link](#factory-methods)] + ```Ruby class Person @@ -2445,7 +2445,7 @@ no parameters. * Prefer [duck-typing](http://en.wikipedia.org/wiki/Duck_typing) over inheritance. -[[link](#duck-typing)] + ```Ruby # bad @@ -2486,7 +2486,7 @@ no parameters. * Avoid the usage of class (`@@`) variables due to their "nasty" behavior in inheritance. -[[link](#no-class-vars)] + ```Ruby class Parent @@ -2512,14 +2512,14 @@ no parameters. Assign proper visibility levels to methods (`private`, `protected`) in accordance with their intended usage. Don't go off leaving everything `public` (which is the default). After all we're coding in *Ruby* now, not in *Python*. -[[link](#visibility)] + * Indent the `public`, `protected`, and `private` methods as much as the method definitions they apply to. Leave one blank line above the visibility modifier and one blank line below in order to emphasize that it applies to all methods below it. -[[link](#indent-public-private-protected)] + ```Ruby class SomeClass @@ -2542,7 +2542,7 @@ no parameters. * Use `def self.method` to define class methods. This makes the code easier to refactor since the class name is not repeated. -[[link](#def-self-class-methods)] + ```Ruby class TestClass @@ -2575,7 +2575,7 @@ no parameters. resolution of `self` in this context is also lexical, and it communicates clearly to the user that the indirection of your alias will not be altered at runtime or by any subclass unless made explicit. -[[link](#alias-method-lexically)] + ```Ruby class Westerner @@ -2622,7 +2622,7 @@ no parameters. Always use `alias_method` when aliasing methods of modules, classes, or singleton classes at runtime, as the lexical scope of `alias` leads to unpredictability in these cases. -[[link](#alias-method)] + ```Ruby module Mononymous @@ -2642,7 +2642,7 @@ no parameters. Signal exceptions using the `fail` method. Use `raise` only when catching an exception and re-raising it (because here you're not failing, but explicitly and purposefully raising an exception). -[[link](#fail-method)] + ```Ruby begin @@ -2655,7 +2655,7 @@ no parameters. * Don't specify `RuntimeError` explicitly in the two argument version of `fail/raise`. -[[link](#no-explicit-runtimeerror)] + ```Ruby # bad @@ -2668,7 +2668,7 @@ no parameters. * Prefer supplying an exception class and a message as two separate arguments to `fail/raise`, instead of an exception instance. -[[link](#exception-class-messages)] + ```Ruby # bad @@ -2685,7 +2685,7 @@ no parameters. inside an `ensure` block, the return will take precedence over any exception being raised, and the method will return as if no exception had been raised at all. In effect, the exception will be silently thrown away. -[[link](#no-return-ensure)] + ```Ruby def foo @@ -2697,7 +2697,7 @@ no parameters. * Use *implicit begin blocks* where possible. -[[link](#begin-implicit)] + ```Ruby # bad @@ -2720,7 +2720,7 @@ no parameters. * Mitigate the proliferation of `begin` blocks by using *contingency methods* (a term coined by Avdi Grimm). -[[link](#contingency-methods)] + ```Ruby # bad @@ -2750,7 +2750,7 @@ no parameters. * Don't suppress exceptions. -[[link](#dont-hide-exceptions)] + ```Ruby # bad @@ -2766,7 +2766,7 @@ no parameters. * Avoid using `rescue` in its modifier form. -[[link](#no-rescue-modifiers)] + ```Ruby # bad - this catches exceptions of StandardError class and its descendant classes @@ -2782,7 +2782,7 @@ no parameters. * Don't use exceptions for flow of control. -[[link](#no-exceptional-flows)] + ```Ruby # bad @@ -2803,7 +2803,7 @@ no parameters. * Avoid rescuing the `Exception` class. This will trap signals and calls to `exit`, requiring you to `kill -9` the process. -[[link](#no-blind-rescues)] + ```Ruby # bad @@ -2835,7 +2835,7 @@ no parameters. * Put more specific exceptions higher up the rescue chain, otherwise they'll never be rescued from. -[[link](#exception-ordering)] + ```Ruby # bad @@ -2859,7 +2859,7 @@ no parameters. * Release external resources obtained by your program in an `ensure` block. -[[link](#release-resources)] + ```Ruby f = File.open('testfile') @@ -2875,7 +2875,7 @@ no parameters. * Use versions of resource obtaining methods that do automatic resource cleanup when possible. -[[link](#auto-release-resources)] + ```Ruby # bad - you need to close the file descriptor explicitly @@ -2892,14 +2892,14 @@ resource cleanup when possible. * Favor the use of exceptions for the standard library over introducing new exception classes. -[[link](#standard-exceptions)] + ## Collections * Prefer literal array and hash creation notation (unless you need to pass parameters to their constructors, that is). -[[link](#literal-array-hash)] + ```Ruby # bad @@ -2915,7 +2915,7 @@ resource cleanup when possible. Prefer `%w` to the literal array syntax when you need an array of words (non-empty strings without spaces and special characters in them). Apply this rule only to arrays with two or more elements. -[[link](#percent-w)] + ```Ruby # bad @@ -2929,7 +2929,7 @@ resource cleanup when possible. Prefer `%i` to the literal array syntax when you need an array of symbols (and you don't need to maintain Ruby 1.9 compatibility). Apply this rule only to arrays with two or more elements. -[[link](#percent-i)] + ```Ruby # bad @@ -2942,7 +2942,7 @@ resource cleanup when possible. * Avoid comma after the last item of an `Array` or `Hash` literal, especially when the items are not on separate lines. -[[link](#no-trailing-array-commas)] + ```Ruby # bad - easier to move/add/remove items, but still not preferred @@ -2961,7 +2961,7 @@ resource cleanup when possible. * Avoid the creation of huge gaps in arrays. -[[link](#no-gappy-arrays)] + ```Ruby arr = [] @@ -2971,18 +2971,18 @@ resource cleanup when possible. * When accessing the first or last element from an array, prefer `first` or `last` over `[0]` or `[-1]`. -[[link](#first-and-last)] + * Use `Set` instead of `Array` when dealing with unique elements. `Set` implements a collection of unordered values with no duplicates. This is a hybrid of `Array`'s intuitive inter-operation facilities and `Hash`'s fast lookup. -[[link](#set-vs-array)] + * Prefer symbols instead of strings as hash keys. -[[link](#symbols-as-keys)] + ```Ruby # bad @@ -2994,11 +2994,11 @@ resource cleanup when possible. * Avoid the use of mutable objects as hash keys. -[[link](#no-mutable-keys)] + * Use the Ruby 1.9 hash literal syntax when your hash keys are symbols. -[[link](#hash-literals)] + ```Ruby # bad @@ -3012,7 +3012,7 @@ resource cleanup when possible. Don't mix the Ruby 1.9 hash syntax with hash rockets in the same hash literal. When you've got keys that are not symbols stick to the hash rockets syntax. -[[link](#no-mixed-hash-syntaces)] + ```Ruby # bad @@ -3027,7 +3027,7 @@ resource cleanup when possible. `Hash#has_value?`. As noted [here](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/43765) by Matz, the longer forms are considered deprecated. -[[link](#hash-key)] + ```Ruby # bad @@ -3041,7 +3041,7 @@ resource cleanup when possible. * Use `Hash#fetch` when dealing with hash keys that should be present. -[[link](#hash-fetch)] + ```Ruby heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' } @@ -3056,7 +3056,7 @@ resource cleanup when possible. * Introduce default values for hash keys via `Hash#fetch` as opposed to using custom logic. -[[link](#hash-fetch-defaults)] + ```Ruby batman = { name: 'Bruce Wayne', is_evil: false } @@ -3071,7 +3071,7 @@ resource cleanup when possible. * Prefer the use of the block instead of the default value in `Hash#fetch` if the code that has to be evaluated may have side effects or be expensive. - [[link](#use-hash-blocks)] + ```Ruby batman = { name: 'Bruce Wayne' } @@ -3087,7 +3087,7 @@ resource cleanup when possible. * Use `Hash#values_at` when you need to retrieve several values consecutively from a hash. -[[link](#hash-values-at)] + ```Ruby # bad @@ -3100,17 +3100,17 @@ resource cleanup when possible. * Rely on the fact that as of Ruby 1.9 hashes are ordered. -[[link](#ordered-hashes)] + * Do not modify a collection while traversing it. -[[link](#no-modifying-collections)] + * When accessing elements of a collection, avoid direct access via `[n]` by using an alternate form of the reader method if it is supplied. This guards you from calling `[]` on `nil`. -[[link](#accessing-elements-directly)] + ```Ruby # bad @@ -3124,7 +3124,7 @@ resource cleanup when possible. When providing an accessor for a collection, provide an alternate form to save users from checking for `nil` before accessing an element in the collection. -[[link](#provide-alternate-accessor-to-collections)] + ```Ruby # bad @@ -3147,7 +3147,7 @@ resource cleanup when possible. * Prefer string interpolation and string formatting instead of string concatenation: -[[link](#string-interpolation)] + ```Ruby # bad @@ -3162,7 +3162,7 @@ resource cleanup when possible. * With interpolated expressions, there should be no padded-spacing inside the braces. -[[link](#string-interpolation)] + ```Ruby # bad @@ -3176,7 +3176,7 @@ resource cleanup when possible. Adopt a consistent string literal quoting style. There are two popular styles in the Ruby community, both of which are considered good - single quotes by default (Option A) and double quotes by default (Option B). -[[link](#consistent-string-literals)] + * **(Option A)** Prefer single-quoted strings when you don't need string interpolation or special symbols such as `\t`, `\n`, `'`, @@ -3207,7 +3207,7 @@ resource cleanup when possible. Don't use the character literal syntax `?x`. Since Ruby 1.9 it's basically redundant - `?x` would interpreted as `'x'` (a string with a single character in it). -[[link](#no-character-literals)] + ```Ruby # bad @@ -3220,7 +3220,7 @@ resource cleanup when possible. * Don't leave out `{}` around instance and global variables being interpolated into a string. -[[link](#curlies-interpolate)] + ```Ruby class Person @@ -3253,7 +3253,7 @@ resource cleanup when possible. * Don't use `Object#to_s` on interpolated objects. It's invoked on them automatically. -[[link](#no-to-s)] + ```Ruby # bad @@ -3268,7 +3268,7 @@ resource cleanup when possible. Instead, use `String#<<`. Concatenation mutates the string instance in-place and is always faster than `String#+`, which creates a bunch of new string objects. -[[link](#concat-strings)] + ```Ruby # good and also fast @@ -3282,7 +3282,7 @@ resource cleanup when possible. * Don't use `String#gsub` in scenarios in which you can use a faster more specialized alternative. -[[link](#dont-abuse-gsub)] + ```Ruby url = 'http://example.com' @@ -3301,7 +3301,7 @@ resource cleanup when possible. When using heredocs for multi-line strings keep in mind the fact that they preserve leading whitespace. It's a good practice to employ some margin based on which to trim the excessive whitespace. -[[link](#heredocs)] + ```Ruby code = <<-END.gsub(/^\s+\|/, '') @@ -3322,11 +3322,11 @@ resource cleanup when possible. * Don't use regular expressions if you just need plain text search in string: `string['text']` -[[link](#no-regexp-for-plaintext)] + * For simple constructions you can use regexp directly through string index. -[[link](#regexp-string-index)] + ```Ruby match = string[/regexp/] # get content of matched regexp @@ -3336,7 +3336,7 @@ resource cleanup when possible. * Use non-capturing groups when you don't use captured result of parentheses. -[[link](#non-capturing-regexp)] + ```Ruby /(first|second)/ # bad @@ -3346,7 +3346,7 @@ resource cleanup when possible. * Don't use the cryptic Perl-legacy variables denoting last regexp group matches (`$1`, `$2`, etc). Use `Regexp.last_match(n)` instead. -[[link](#no-perl-regexp-last-matchers)] + ```Ruby /(regexp)/ =~ string @@ -3362,7 +3362,7 @@ resource cleanup when possible. * Avoid using numbered groups as it can be hard to track what they contain. Named groups can be used instead. -[[link](#no-numbered-regexes)] + ```Ruby # bad @@ -3379,13 +3379,13 @@ resource cleanup when possible. * Character classes have only a few special characters you should care about: `^`, `-`, `\`, `]`, so don't escape `.` or brackets in `[]`. -[[link](#limit-escapes)] + * Be careful with `^` and `$` as they match start/end of line, not string endings. If you want to match the whole string use: `\A` and `\z` (not to be confused with `\Z` which is the equivalent of `/\n?\z/`). -[[link](#caret-and-dollar-regexp)] + ```Ruby string = "some injection\nusername" @@ -3396,7 +3396,7 @@ resource cleanup when possible. * Use `x` modifier for complex regexps. This makes them more readable and you can add some useful comments. Just be careful as spaces are ignored. -[[link](#comment-regexes)] + ```Ruby regexp = / @@ -3410,7 +3410,7 @@ resource cleanup when possible. * For complex replacements `sub`/`gsub` can be used with block or hash. -[[link](#gsub-blocks)] + ## Percent Literals @@ -3418,7 +3418,7 @@ resource cleanup when possible. Use `%()`(it's a shorthand for `%Q`) for single-line strings which require both interpolation and embedded double-quotes. For multi-line strings, prefer heredocs. -[[link](#percent-q-shorthand)] + ```Ruby # bad (no interpolation needed) @@ -3441,7 +3441,7 @@ resource cleanup when possible. Avoid `%q` unless you have a string with both `'` and `"` in it. Regular string literals are more readable and should be preferred unless a lot of characters would have to be escaped in them. -[[link](#percent-q)] + ```Ruby # bad @@ -3458,7 +3458,7 @@ resource cleanup when possible. * Use `%r` only for regular expressions matching *at least* one '/' character. -[[link](#percent-r)] + ```Ruby # bad @@ -3472,7 +3472,7 @@ resource cleanup when possible. * Avoid the use of `%x` unless you're going to invoke a command with backquotes in it(which is rather unlikely). -[[link](#percent-x)] + ```Ruby # bad @@ -3486,14 +3486,14 @@ resource cleanup when possible. * Avoid the use of `%s`. It seems that the community has decided `:"some string"` is the preferred way to create a symbol with spaces in it. -[[link](#percent-s)] + * Prefer `()` as delimiters for all `%` literals, except `%r`. Since parentheses often appear inside regular expressions in many scenarios a less common character like `{` might be a better choice for a delimiter, depending on the regexp's content. -[[link](#percent-literal-braces)] + ```Ruby # bad @@ -3509,18 +3509,18 @@ resource cleanup when possible. * Avoid needless metaprogramming. -[[link](#no-needless-metaprogramming)] + * Do not mess around in core classes when writing libraries. (Do not monkey-patch them.) -[[link](#no-monkey-patching)] + * The block form of `class_eval` is preferable to the string-interpolated form. - when you use the string-interpolated form, always supply `__FILE__` and `__LINE__`, so that your backtraces make sense: -[[link](#block-class-eval)] + ```ruby class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__ @@ -3532,7 +3532,7 @@ resource cleanup when possible. When using `class_eval` (or other `eval`) with string interpolation, add a comment block showing its appearance if interpolated (a practice used in Rails code): -[[link](#eval-comment-docs)] + ```ruby # from activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -3558,7 +3558,7 @@ resource cleanup when possible. might silently work, e.g. `nukes.launch_state = false`. Consider using delegation, proxy, or `define_method` instead. If you must use `method_missing`: -[[link](#no-method-missing)] + - Be sure to [also define `respond_to_missing?`](http://blog.marc-andre.ca/2010/11/methodmissing-politely.html) - Only catch methods with a well-defined prefix, such as `find_by_*` -- make your code as assertive as possible. @@ -3589,36 +3589,36 @@ resource cleanup when possible. * Prefer `public_send` over `send` so as not to circumvent `private`/`protected` visibility. -[[link](#prefer-public-send)] + ## Misc * Write `ruby -w` safe code. -[[link](#always-warn)] + * Avoid hashes as optional parameters. Does the method do too much? (Object initializers are exceptions for this rule). -[[link](#no-optional-hash-params)] + * Avoid methods longer than 10 LOC (lines of code). Ideally, most methods will be shorter than 5 LOC. Empty lines do not contribute to the relevant LOC. -[[link](#short-methods)] + * Avoid parameter lists longer than three or four parameters. -[[link](#too-many-params)] + * If you really need "global" methods, add them to Kernel and make them private. -[[link](#private-global-methods)] + * Use module instance variables instead of global variables. -[[link](#instance-vars)] + ```Ruby # bad @@ -3637,31 +3637,31 @@ resource cleanup when possible. * Use `OptionParser` for parsing complex command line options and `ruby -s` for trivial command line options. -[[link](#optionparser)] + * Prefer `Time.now` over `Time.new` when retrieving the current system time. -[[link](#time-now)] + * Code in a functional way, avoiding mutation when that makes sense. -[[link](#functional-code)] + * Do not mutate parameters unless that is the purpose of the method. -[[link](#no-param-mutations)] + * Avoid more than three levels of block nesting. -[[link](#three-is-the-number-thou-shalt-count)] + * Be consistent. In an ideal world, be consistent with these guidelines. -[[link](#be-consistent)] + * Use common sense. -[[link](#common-sense)] + ## Tools