STYLEGUIDE.md in rubocop-github-0.18.0 vs STYLEGUIDE.md in rubocop-github-0.19.0
- old
+ new
@@ -1,39 +1,44 @@
# Ruby Style Guide
-* Use soft-tabs with a two space indent.
+This is GitHub's Ruby Style Guide, inspired by [RuboCop's guide][rubocop-guide].
-* Keep each line of code to a readable length. Unless you have a reason to, keep lines to a maximum of 118 characters. Why 118? That's the width at which the pull request diff UI needs horizontal scrolling (making pull requests harder to review).
+## Table of Contents
+1. [Layout](#layout)
+ 1. [Indentation](#indentation)
+ 2. [Inline](#inline)
+ 3. [Newlines](#newlines)
+2. [Maximum Line Length](#line-length)
+3. [Classes](#classes)
+4. [Collections](#collections)
+5. [Documentation](#documentation)
+6. [Dynamic Dispatch](#dynamic-dispatch)
+7. [Exceptions](#exceptions)
+8. [Hashes](#hashes)
+9. [Keyword Arguments](#keyword-arguments)
+10. [Naming](#naming)
+11. [Percent Literals](#percent-literals)
+12. [Regular Expressions](#regular-expressions)
+13. [Requires](#requires)
+14. [Strings](#strings)
+15. [Methods](#methods)
+ 1. [Method definitions](#method-definitions)
+ 2. [Method calls](#method-calls)
+16. [Conditional Expressions](#conditional-expressions)
+ 1. [Conditional keywords](#conditional-keywords)
+ 2. [Ternary operator](#ternary-operator)
+17. [Syntax](#syntax)
-* Never leave trailing whitespace.
+## Layout
-* End each file with a [newline](https://github.com/bbatsov/ruby-style-guide#newline-eof).
+### Indentation
-* Use spaces around operators, after commas, colons and semicolons, around `{`
- and before `}`.
+* Use soft-tabs with a two space indent.
+ <a name="default-indentation"></a><sup>[[link](#default-indentation)]</sup>
-``` ruby
-sum = 1 + 2
-a, b = 1, 2
-1 > 2 ? true : false; puts "Hi"
-[1, 2, 3].each { |e| puts e }
-```
-
-* No spaces after `(`, `[` or before `]`, `)`.
-
-``` ruby
-some(arg).other
-[1, 2, 3].length
-```
-
-* No spaces after `!`.
-
-``` ruby
-!array.include?(element)
-```
-
* Indent `when` with the start of the `case` expression.
+ <a name="indent-when-as-start-of-case"></a><sup>[[link](#indent-when-as-start-of-case)]</sup>
``` ruby
# bad
message = case
when song.name == "Misty"
@@ -69,12 +74,49 @@
else
song.play
end
```
+### Inline
+
+* Never leave trailing whitespace.
+ <a name="trailing-whitespace"></a><sup>[[link](#trailing-whitespace)]</sup>
+
+* Use spaces around operators, after commas, colons and semicolons, around `{`
+ and before `}`.
+ <a name="spaces-operators"></a><sup>[[link](#spaces-operators)]</sup>
+
+``` ruby
+sum = 1 + 2
+a, b = 1, 2
+1 > 2 ? true : false; puts "Hi"
+[1, 2, 3].each { |e| puts e }
+```
+
+* No spaces after `(`, `[` or before `]`, `)`.
+ <a name="no-spaces-braces"></a><sup>[[link](#no-spaces-braces)]</sup>
+
+``` ruby
+some(arg).other
+[1, 2, 3].length
+```
+
+* No spaces after `!`.
+ <a name="no-spaces-bang"></a><sup>[[link](#no-spaces-bang)]</sup>
+
+``` ruby
+!array.include?(element)
+```
+
+### Newlines
+
+* End each file with a [newline](https://github.com/bbatsov/ruby-style-guide#newline-eof).
+ <a name="newline-eof"></a><sup>[[link](#newline-eof)]</sup>
+
* Use empty lines between `def`s and to break up a method into logical
paragraphs.
+ <a name="empty-lines-def"></a><sup>[[link](#empty-lines-def)]</sup>
``` ruby
def some_method
data = initialize(options)
@@ -86,14 +128,20 @@
def some_method
result
end
```
+## Maximum Line Length
+
+* Keep each line of code to a readable length. Unless you have a reason to, keep lines to a maximum of 118 characters. Why 118? That's the width at which the pull request diff UI needs horizontal scrolling (making pull requests harder to review).
+ <a name="line-length"></a><sup>[[link](#line-length)]</sup>
+
## Classes
* Avoid the usage of class (`@@`) variables due to their unusual behavior
in inheritance.
+ <a name="class-variables"></a><sup>[[link](#class-variables)]</sup>
``` ruby
class Parent
@@class_var = "parent"
@@ -113,10 +161,11 @@
class variable. Class instance variables should usually be preferred
over class variables.
* Use `def self.method` to define singleton methods. This makes the methods
more resistant to refactoring changes.
+ <a name="singleton-methods"></a><sup>[[link](#singleton-methods)]</sup>
``` ruby
class TestClass
# bad
def TestClass.some_method
@@ -129,10 +178,11 @@
end
```
* Avoid `class << self` except when necessary, e.g. single accessors and aliased
attributes.
+ <a name="class-method-definitions"></a><sup>[[link](#class-method-definitions)]</sup>
``` ruby
class TestClass
# bad
class << self
@@ -161,10 +211,11 @@
end
```
* Indent the `public`, `protected`, and `private` methods as much the
method definitions they apply to. Leave one blank line above them.
+ <a name="access-modifier-identation"></a><sup>[[link](#access-modifier-identation)]</sup>
``` ruby
class SomeClass
def public_method
# ...
@@ -177,10 +228,11 @@
end
```
* Avoid explicit use of `self` as the recipient of internal class or instance
messages unless to specify a method shadowed by a variable.
+ <a name="self-messages"></a><sup>[[link](#self-messages)]</sup>
``` ruby
class SomeClass
attr_accessor :message
@@ -193,10 +245,11 @@
## Collections
* Prefer `%w` to the literal array syntax when you need an array of
strings.
+ <a name="percent-w"></a><sup>[[link](#percent-w)]</sup>
``` ruby
# bad
STATES = ["draft", "open", "closed"]
@@ -206,12 +259,14 @@
* 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.
+ <a name="prefer-set"></a><sup>[[link](#prefer-set)]</sup>
* Use symbols instead of strings as hash keys.
+ <a name="symbols-as-keys"></a><sup>[[link](#symbols-as-keys)]</sup>
``` ruby
# bad
hash = { "one" => 1, "two" => 2, "three" => 3 }
@@ -220,10 +275,11 @@
```
## Documentation
Use [TomDoc](http://tomdoc.org) to the best of your ability. It's pretty sweet:
+<a name="tomdoc"></a><sup>[[link](#tomdoc)]</sup>
``` ruby
# Public: Duplicate some text an arbitrary number of times.
#
# text - The String to be duplicated.
@@ -241,10 +297,11 @@
```
## Dynamic Dispatch
Avoid calling `send` and its cousins unless you really need it. Metaprogramming can be extremely powerful, but in most cases you can write code that captures your meaning by being explicit:
+<a name="avoid-send"></a><sup>[[link](#avoid-send)]</sup>
``` ruby
# avoid
unless [:base, :head].include?(base_or_head)
raise ArgumentError, "base_or_head must be either :base or :head"
@@ -266,10 +323,11 @@
end
```
## Exceptions
* Don't use exceptions for flow of control.
+ <a name="exceptions-flow-control"></a><sup>[[link](#exceptions-flow-control)]</sup>
``` ruby
# bad
begin
n / d
@@ -284,10 +342,11 @@
n / d
end
```
* Rescue specific exceptions, not `StandardError` or its superclasses.
+ <a name="specific-exceptions"></a><sup>[[link](#specific-exceptions)]</sup>
``` ruby
# bad
begin
# an exception occurs here
@@ -304,10 +363,11 @@
```
## Hashes
Use the Ruby 1.9 syntax for hash literals when all the keys are symbols:
+<a name="symbols-as-hash-keys"></a><sup>[[link](#symbols-as-hash-keys)]</sup>
``` ruby
# bad
user = {
:login => "defunkt",
@@ -320,10 +380,11 @@
name: "Chris Wanstrath"
}
```
Use the 1.9 syntax when calling a method with Hash options arguments or named arguments:
+<a name="symbols-as-hash-method-arguments"></a><sup>[[link](#symbols-as-hash-method-arguments)]</sup>
``` ruby
# bad
user = User.create(:login => "jane")
link_to("Account", :controller => "users", :action => "show", :id => user)
@@ -332,12 +393,15 @@
user = User.create(login: "jane")
link_to("Account", controller: "users", action: "show", id: user)
```
If you have a hash with mixed key types, use the legacy hashrocket style to avoid mixing styles within the same hash:
+<a name="consistent-hash-syntax"></a><sup>[[link](#consistent-hash-syntax)]</sup>
``` ruby
+
+``` ruby
# bad
hsh = {
user_id: 55,
"followers-count" => 1000
}
@@ -350,22 +414,25 @@
```
## Keyword Arguments
[Keyword arguments](http://magazine.rubyist.net/?Ruby200SpecialEn-kwarg) are recommended but not required when a method's arguments may otherwise be opaque or non-obvious when called. Additionally, prefer them over the old "Hash as pseudo-named args" style from pre-2.0 ruby.
+<a name="keyword-arguments"></a><sup>[[link](#keyword-arguments)]</sup>
So instead of this:
+
``` ruby
def remove_member(user, skip_membership_check=false)
# ...
end
# Elsewhere: what does true mean here?
remove_member(user, true)
```
-Do this, which is much clearer.
+Do this, which is much clearer:
+
``` ruby
def remove_member(user, skip_membership_check: false)
# ...
end
@@ -374,34 +441,41 @@
```
## Naming
* Use `snake_case` for methods and variables.
+ <a name="snake-case-methods-vars"></a><sup>[[link](#snake-case-methods-vars)]</sup>
* Use `CamelCase` for classes and modules. (Keep acronyms like HTTP,
RFC, XML uppercase.)
+ <a name="camelcase-classes-modules"></a><sup>[[link](#camelcase-classes-modules)]</sup>
* Use `SCREAMING_SNAKE_CASE` for other constants.
+ <a name="screaming-snake-case-constants"></a><sup>[[link](#screaming-snake-case-constants)]</sup>
* The names of predicate methods (methods that return a boolean value)
should end in a question mark. (i.e. `Array#empty?`).
+ <a name="bool-methods-qmark"></a><sup>[[link](#bool-methods-qmark)]</sup>
* The names of potentially "dangerous" methods (i.e. methods that modify `self` or the
arguments, `exit!`, etc.) should end with an exclamation mark. Bang methods
should only exist if a non-bang counterpart (method name which does NOT end with !)
also exists.
+ <a name="dangerous-method-bang"></a><sup>[[link](#dangerous-method-bang)]</sup>
## Percent Literals
* Use `%w` freely.
+ <a name="use-percent-w-freely"></a><sup>[[link](#use-percent-w-freely)]</sup>
``` ruby
STATES = %w(draft open closed)
```
* Use `%()` for single-line strings which require both interpolation
and embedded double-quotes. For multi-line strings, prefer heredocs.
+ <a name="percent-parens-single-line"></a><sup>[[link](#percent-parens-single-line)]</sup>
``` ruby
# bad (no interpolation needed)
%(<div class="text">Some text</div>)
# should be "<div class=\"text\">Some text</div>"
@@ -417,10 +491,11 @@
# good (requires interpolation, has quotes, single line)
%(<tr><td class="name">#{name}</td>)
```
* Use `%r` only for regular expressions matching *more than* one '/' character.
+ <a name="percent-r-regular-expressions"></a><sup>[[link](#percent-r-regular-expressions)]</sup>
``` ruby
# bad
%r(\s+)
@@ -434,10 +509,11 @@
## Regular Expressions
* Avoid using $1-9 as it can be hard to track what they contain. Named groups
can be used instead.
+ <a name="capture-with-named-groups"></a><sup>[[link](#capture-with-named-groups)]</sup>
``` ruby
# bad
/(regexp)/ =~ string
...
@@ -449,19 +525,21 @@
process meaningful_var
```
* 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`.
+ <a name="regex-begin-end-markers"></a><sup>[[link](#regex-begin-end-markers)]</sup>
``` ruby
string = "some injection\nusername"
string[/^username$/] # matches
string[/\Ausername\z/] # don't match
```
* 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.
+ <a name="x-modifier-complex-regex"></a><sup>[[link](#x-modifier-complex-regex)]</sup>
``` ruby
regexp = %r{
start # some text
\s # white space char
@@ -474,10 +552,11 @@
## Requires
Always `require` dependencies used directly in a script at the start of the same file.
Resources that will get autoloaded on first use—such as Rails models, controllers, or
helpers—don't need to be required.
+<a name="require-dependencies-directly"></a><sup>[[link](#require-dependencies-directly)]</sup>
``` ruby
require "set"
require "time"
@@ -489,10 +568,11 @@
documentation about the libraries that the current file uses.
## Strings
* Prefer string interpolation instead of string concatenation:
+ <a name="string-interpolation"></a><sup>[[link](#string-interpolation)]</sup>
``` ruby
# bad
email_with_name = user.name + " <" + user.email + ">"
@@ -501,10 +581,11 @@
```
* Use double-quoted strings. Interpolation and escaped characters
will always work without a delimiter change, and `'` is a lot more
common than `"` in string literals.
+ <a name="double-quotes"></a><sup>[[link](#double-quotes)]</sup>
``` ruby
# bad
name = 'Bozhidar'
@@ -513,10 +594,11 @@
```
* Avoid using `String#+` when you need to construct large data chunks.
Instead, use `String#<<`. Concatenation mutates the string instance in-place
and is always faster than `String#+`, which creates a bunch of new string objects.
+ <a name="string-concatenation"></a><sup>[[link](#string-concatenation)]</sup>
``` ruby
# good and also fast
html = ""
html << "<h1>Page title</h1>"
@@ -524,14 +606,17 @@
paragraphs.each do |paragraph|
html << "<p>#{paragraph}</p>"
end
```
-## Syntax
+## Methods
+### Method definitions
+
* Use `def` with parentheses when there are arguments. Omit the
parentheses when the method doesn't accept any arguments.
+ <a name="method-parens-when-arguments"></a><sup>[[link](#method-parens-when-arguments)]</sup>
``` ruby
def some_method
# body omitted
end
@@ -539,29 +624,34 @@
def some_method_with_arguments(arg1, arg2)
# body omitted
end
```
-* Never use `for`, unless you know exactly why. Most of the time iterators
- should be used instead. `for` is implemented in terms of `each` (so
- 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.
+### Method calls
-``` ruby
-arr = [1, 2, 3]
+* 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)`.
+ <a name="parens-no-spaces"></a><sup>[[link](#parens-no-spaces)]</sup>
+* Never put a space between a method name and the opening parenthesis.
+ <a name="no-spaces-method-parens"></a><sup>[[link](#no-spaces-method-parens)]</sup>
+
+``` ruby
# bad
-for elem in arr do
- puts elem
-end
+f (3 + 2) + 1
# good
-arr.each { |elem| puts elem }
+f(3 + 2) + 1
```
+## Conditional Expressions
+
+### Conditional keywords
+
* Never use `then` for multi-line `if/unless`.
+ <a name="no-then-for-multi-line-if-unless"></a><sup>[[link](#no-then-for-multi-line-if-unless)]</sup>
``` ruby
# bad
if some_condition then
# body omitted
@@ -571,44 +661,16 @@
if some_condition
# body omitted
end
```
-* Avoid the ternary operator (`?:`) except in cases where all expressions are extremely
- trivial. However, do use the ternary operator(`?:`) over `if/then/else/end` constructs
- for single line conditionals.
-
-``` ruby
-# bad
-result = if some_condition then something else something_else end
-
-# good
-result = some_condition ? something : something_else
-```
-
-* 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.
-
-``` ruby
-# bad
-some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
-
-# good
-if some_condition
- nested_condition ? nested_something : nested_something_else
-else
- something_else
-end
-```
-
* The `and` and `or` keywords are banned. It's just not worth it. Always use `&&` and `||` instead.
+ <a name="no-and-or-or"></a><sup>[[link](#no-and-or-or)]</sup>
-* Avoid multi-line `?:` (the ternary operator), use `if/unless` instead.
-
* Favor modifier `if/unless` usage when you have a single-line
body.
+ <a name="favor-modifier-if-unless"></a><sup>[[link](#favor-modifier-if-unless)]</sup>
``` ruby
# bad
if some_condition
do_something
@@ -617,10 +679,11 @@
# good
do_something if some_condition
```
* Never use `unless` with `else`. Rewrite these with the positive case first.
+ <a name="no-else-with-unless"></a><sup>[[link](#no-else-with-unless)]</sup>
``` ruby
# bad
unless success?
puts "failure"
@@ -635,10 +698,11 @@
puts "failure"
end
```
* Don't use parentheses around the condition of an `if/unless/while`.
+ <a name="no-parens-if-unless-while"></a><sup>[[link](#no-parens-if-unless-while)]</sup>
``` ruby
# bad
if (x > 10)
# body omitted
@@ -648,15 +712,72 @@
if x > 10
# body omitted
end
```
+### Ternary operator
+
+* Avoid the ternary operator (`?:`) except in cases where all expressions are extremely
+ trivial. However, do use the ternary operator(`?:`) over `if/then/else/end` constructs
+ for single line conditionals.
+ <a name="trivial-ternary"></a><sup>[[link](#trivial-ternary)]</sup>
+
+``` ruby
+# bad
+result = if some_condition then something else something_else end
+
+# good
+result = some_condition ? something : something_else
+```
+
+* Avoid multi-line `?:` (the ternary operator), use `if/unless` instead.
+ <a name="no-multiline-ternary"></a><sup>[[link](#no-multiline-ternary)]</sup>
+
+* 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.
+ <a name="one-expression-per-branch"></a><sup>[[link](#one-expression-per-branch)]</sup>
+
+``` ruby
+# bad
+some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
+
+# good
+if some_condition
+ nested_condition ? nested_something : nested_something_else
+else
+ something_else
+end
+```
+
+## Syntax
+
+* Never use `for`, unless you know exactly why. Most of the time iterators
+ should be used instead. `for` is implemented in terms of `each` (so
+ 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.
+ <a name="avoid-for"></a><sup>[[link](#avoid-for)]</sup>
+
+``` ruby
+arr = [1, 2, 3]
+
+# bad
+for elem in arr do
+ puts elem
+end
+
+# good
+arr.each { |elem| puts elem }
+```
+
* Prefer `{...}` over `do...end` for single-line blocks. Avoid using
`{...}` 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.
+ <a name="squiggly-braces"></a><sup>[[link](#squiggly-braces)]</sup>
``` ruby
names = ["Bozhidar", "Steve", "Sarah"]
# good
@@ -674,15 +795,16 @@
names.select do |name|
name.start_with?("S")
end.map { |name| name.upcase }
```
- Some will argue that multiline chaining would look OK with the use of {...}, but they should
- ask themselves - is this code really readable and can't the block's contents be extracted into
- nifty methods?
+* Some will argue that multiline chaining would look OK with the use of `{...}`,
+ but they should ask themselves: is this code really readable and can't the block's
+ contents be extracted into nifty methods?
* Avoid `return` where not required.
+ <a name="avoid-return"></a><sup>[[link](#avoid-return)]</sup>
``` ruby
# bad
def some_method(some_arr)
return some_arr.size
@@ -693,10 +815,11 @@
some_arr.size
end
```
* Use spaces around the `=` operator when assigning default values to method parameters:
+ <a name="spaces-around-equals"></a><sup>[[link](#spaces-around-equals)]</sup>
``` ruby
# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
# do something...
@@ -710,10 +833,11 @@
While several Ruby books suggest the first style, the second is much more prominent
in practice (and arguably a bit more readable).
* Using the return value of `=` (an assignment) is ok.
+ <a name="use-return-value-of-assignment"></a><sup>[[link](#use-return-value-of-assignment)]</sup>
``` ruby
# bad
if (v = array.grep(/foo/)) ...
@@ -723,18 +847,20 @@
# also good - has correct precedence.
if (v = next_value) == "hello" ...
```
* Use `||=` freely to initialize variables.
+ <a name="memoization-for-initialization"></a><sup>[[link](#memoize-away)]</sup>
``` ruby
# set name to Bozhidar, only if it's nil or false
name ||= "Bozhidar"
```
* Don't use `||=` to initialize boolean variables. (Consider what
would happen if the current value happened to be `false`.)
+ <a name="no-memoization-for-boolean"></a><sup>[[link](#no-memoization-for-boolean)]</sup>
``` ruby
# bad - would set enabled to true even if it was false
enabled ||= true
@@ -744,26 +870,14 @@
* Avoid using Perl-style special variables (like `$0-9`, `$`,
etc. ). They are quite cryptic and their use in anything but
one-liner scripts is discouraged. Prefer long form versions such as
`$PROGRAM_NAME`.
+ <a name="no-cryptic-vars"></a><sup>[[link](#no-cryptic-vars)]</sup>
-* Never put a space between a method name and the opening parenthesis.
-
-``` ruby
-# bad
-f (3 + 2) + 1
-
-# good
-f(3 + 2) + 1
-```
-
-* 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)`.
-
* Use `_` for unused block parameters.
+ <a name="underscore-unused-vars"></a><sup>[[link](#underscore-unused-vars)]</sup>
``` ruby
# bad
result = hash.map { |k, v| v + 1 }
@@ -773,7 +887,10 @@
* Don't use the `===` (threequals) operator to check types. `===` is mostly an
implementation detail to support Ruby features like `case`, and it's not commutative.
For example, `String === "hi"` is true and `"hi" === String` is false.
Instead, use `is_a?` or `kind_of?` if you must.
+ <a name="type-checking-is-a-kind-of"></a><sup>[[link](#type-checking-is-a-kind-of)]</sup>
Refactoring is even better. It's worth looking hard at any code that explicitly checks types.
+
+[rubocop-guide]: https://github.com/rubocop-hq/ruby-style-guide