diff --git a/README.md b/README.md
index b8af92a1..ab466b18 100644
--- a/README.md
+++ b/README.md
@@ -29,8 +29,10 @@ If you are using a rubocop version < 1.0.0, you can use rubocop-github version
## Testing
-`bundle install`
-`bundle exec rake test`
+``` bash
+bundle install
+bundle exec rake test
+```
## The Cops
diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md
index 829f4b2c..b10d59c3 100644
--- a/STYLEGUIDE.md
+++ b/STYLEGUIDE.md
@@ -1,37 +1,42 @@
# Ruby Style Guide
-* Use soft-tabs with a two space indent.
-
-* 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).
-
-* Never leave trailing whitespace.
-
-* End each file with a [newline](https://github.com/bbatsov/ruby-style-guide#newline-eof).
-
-* Use spaces around operators, after commas, colons and semicolons, around `{`
- and before `}`.
-
-``` 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 `!`.
+This is GitHub's Ruby Style Guide, inspired by [RuboCop's guide][rubocop-guide].
+
+## 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)
+
+## Layout
+
+### Indentation
-``` ruby
-!array.include?(element)
-```
+* Use soft-tabs with a two space indent.
+ [[link](#default-indentation)]
* Indent `when` with the start of the `case` expression.
+ [[link](#indent-when-as-start-of-case)]
``` ruby
# bad
@@ -71,8 +76,45 @@ else
end
```
+### Inline
+
+* Never leave trailing whitespace.
+ [[link](#trailing-whitespace)]
+
+* Use spaces around operators, after commas, colons and semicolons, around `{`
+ and before `}`.
+ [[link](#spaces-operators)]
+
+``` 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 `]`, `)`.
+ [[link](#no-spaces-braces)]
+
+``` ruby
+some(arg).other
+[1, 2, 3].length
+```
+
+* No spaces after `!`.
+ [[link](#no-spaces-bang)]
+
+``` ruby
+!array.include?(element)
+```
+
+### Newlines
+
+* End each file with a [newline](https://github.com/bbatsov/ruby-style-guide#newline-eof).
+ [[link](#newline-eof)]
+
* Use empty lines between `def`s and to break up a method into logical
paragraphs.
+ [[link](#empty-lines-def)]
``` ruby
def some_method
@@ -88,10 +130,16 @@ def some_method
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).
+ [[link](#line-length)]
+
## Classes
* Avoid the usage of class (`@@`) variables due to their unusual behavior
in inheritance.
+ [[link](#class-variables)]
``` ruby
class Parent
@@ -115,6 +163,7 @@ Parent.print_class_var # => will print "child"
* Use `def self.method` to define singleton methods. This makes the methods
more resistant to refactoring changes.
+ [[link](#singleton-methods)]
``` ruby
class TestClass
@@ -131,6 +180,7 @@ class TestClass
* Avoid `class << self` except when necessary, e.g. single accessors and aliased
attributes.
+ [[link](#class-method-definitions)]
``` ruby
class TestClass
@@ -163,6 +213,7 @@ end
* Indent the `public`, `protected`, and `private` methods as much the
method definitions they apply to. Leave one blank line above them.
+ [[link](#access-modifier-identation)]
``` ruby
class SomeClass
@@ -179,6 +230,7 @@ end
* Avoid explicit use of `self` as the recipient of internal class or instance
messages unless to specify a method shadowed by a variable.
+ [[link](#self-messages)]
``` ruby
class SomeClass
@@ -195,6 +247,7 @@ end
* Prefer `%w` to the literal array syntax when you need an array of
strings.
+ [[link](#percent-w)]
``` ruby
# bad
@@ -208,8 +261,10 @@ STATES = %w(draft open closed)
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](#prefer-set)]
* Use symbols instead of strings as hash keys.
+ [[link](#symbols-as-keys)]
``` ruby
# bad
@@ -222,6 +277,7 @@ hash = { one: 1, two: 2, three: 3 }
## Documentation
Use [TomDoc](http://tomdoc.org) to the best of your ability. It's pretty sweet:
+[[link](#tomdoc)]
``` ruby
# Public: Duplicate some text an arbitrary number of times.
@@ -243,6 +299,7 @@ end
## 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:
+[[link](#avoid-send)]
``` ruby
# avoid
@@ -268,6 +325,7 @@ end
## Exceptions
* Don't use exceptions for flow of control.
+ [[link](#exceptions-flow-control)]
``` ruby
# bad
@@ -286,6 +344,7 @@ end
```
* Rescue specific exceptions, not `StandardError` or its superclasses.
+ [[link](#specific-exceptions)]
``` ruby
# bad
@@ -306,6 +365,7 @@ end
## Hashes
Use the Ruby 1.9 syntax for hash literals when all the keys are symbols:
+[[link](#symbols-as-hash-keys)]
``` ruby
# bad
@@ -322,6 +382,7 @@ user = {
```
Use the 1.9 syntax when calling a method with Hash options arguments or named arguments:
+[[link](#symbols-as-hash-method-arguments)]
``` ruby
# bad
@@ -334,6 +395,9 @@ 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:
+[[link](#consistent-hash-syntax)]
+
+``` ruby
``` ruby
# bad
@@ -352,6 +416,9 @@ hsh = {
## 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.
+[[link](#keyword-arguments)]
+
+``` ruby
So instead of this:
``` ruby
@@ -376,23 +443,29 @@ remove_member(user, skip_membership_check: true)
## Naming
* Use `snake_case` for methods and variables.
+ [[link](#snake-case-methods-vars)]
* Use `CamelCase` for classes and modules. (Keep acronyms like HTTP,
RFC, XML uppercase.)
+ [[link](#camelcase-classes-modules)]
* Use `SCREAMING_SNAKE_CASE` for other constants.
+ [[link](#screaming-snake-case-constants)]
* The names of predicate methods (methods that return a boolean value)
should end in a question mark. (i.e. `Array#empty?`).
+ [[link](#bool-methods-qmark)]
* 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.
+ [[link](#dangerous-method-bang)]
## Percent Literals
* Use `%w` freely.
+ [[link](#use-percent-w-freely)]
``` ruby
STATES = %w(draft open closed)
@@ -400,6 +473,7 @@ STATES = %w(draft open closed)
* Use `%()` for single-line strings which require both interpolation
and embedded double-quotes. For multi-line strings, prefer heredocs.
+ [[link](#percent-parens-single-line)]
``` ruby
# bad (no interpolation needed)
@@ -419,6 +493,7 @@ STATES = %w(draft open closed)
```
* Use `%r` only for regular expressions matching *more than* one '/' character.
+ [[link](#percent-r-regular-expressions)]
``` ruby
# bad
@@ -436,6 +511,7 @@ STATES = %w(draft open closed)
* Avoid using $1-9 as it can be hard to track what they contain. Named groups
can be used instead.
+ [[link](#capture-with-named-groups)]
``` ruby
# bad
@@ -451,6 +527,7 @@ 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`.
+ [[link](#regex-begin-end-markers)]
``` ruby
string = "some injection\nusername"
@@ -460,6 +537,7 @@ 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.
+ [[link](#x-modifier-complex-regex)]
``` ruby
regexp = %r{
@@ -476,6 +554,7 @@ regexp = %r{
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.
+[[link](#require-dependencies-directly)]
``` ruby
require "set"
@@ -491,6 +570,7 @@ documentation about the libraries that the current file uses.
## Strings
* Prefer string interpolation instead of string concatenation:
+ [[link](#string-interpolation)]
``` ruby
# bad
@@ -503,6 +583,7 @@ email_with_name = "#{user.name} <#{user.email}>"
* 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.
+ [[link](#double-quotes)]
``` ruby
# bad
@@ -515,6 +596,7 @@ name = "Bozhidar"
* 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.
+ [[link](#string-concatenation)]
``` ruby
# good and also fast
@@ -526,10 +608,13 @@ paragraphs.each do |paragraph|
end
```
-## Syntax
+## Methods
+
+### Method definitions
* Use `def` with parentheses when there are arguments. Omit the
parentheses when the method doesn't accept any arguments.
+ [[link](#method-parens-when-arguments)]
``` ruby
def some_method
@@ -541,25 +626,30 @@ end
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)`.
+ [[link](#parens-no-spaces)]
+
+* Never put a space between a method name and the opening parenthesis.
+ [[link](#no-spaces-method-parens)]
+``` 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`.
+ [[link](#no-then-for-multi-line-if-unless)]
``` ruby
# bad
@@ -573,40 +663,12 @@ if some_condition
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.
-
-* Avoid multi-line `?:` (the ternary operator), use `if/unless` instead.
+ [[link](#no-and-or-or)]
* Favor modifier `if/unless` usage when you have a single-line
body.
+ [[link](#favor-modifier-if-unless)]
``` ruby
# bad
@@ -619,6 +681,7 @@ do_something if some_condition
```
* Never use `unless` with `else`. Rewrite these with the positive case first.
+ [[link](#no-else-with-unless)]
``` ruby
# bad
@@ -637,6 +700,7 @@ end
```
* Don't use parentheses around the condition of an `if/unless/while`.
+ [[link](#no-parens-if-unless-while)]
``` ruby
# bad
@@ -650,11 +714,68 @@ if x > 10
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.
+ [[link](#trivial-ternary)]
+
+``` 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.
+ [[link](#no-multiline-ternary)]
+
+* 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](#one-expression-per-branch)]
+
+``` 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.
+ [[link](#avoid-for)]
+
+``` 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.
+ [[link](#squiggly-braces)]
``` ruby
names = ["Bozhidar", "Steve", "Sarah"]
@@ -681,6 +802,7 @@ end.map { |name| name.upcase }
nifty methods?
* Avoid `return` where not required.
+ [[link](#avoid-return)]
``` ruby
# bad
@@ -695,6 +817,7 @@ end
```
* Use spaces around the `=` operator when assigning default values to method parameters:
+ [[link](#spaces-around-equals)]
``` ruby
# bad
@@ -712,6 +835,7 @@ While several Ruby books suggest the first style, the second is much more promin
in practice (and arguably a bit more readable).
* Using the return value of `=` (an assignment) is ok.
+ [[link](#use-return-value-of-assignment)]
``` ruby
# bad
@@ -725,6 +849,7 @@ if (v = next_value) == "hello" ...
```
* Use `||=` freely to initialize variables.
+ [[link](#memoize-away)]
``` ruby
# set name to Bozhidar, only if it's nil or false
@@ -733,6 +858,7 @@ name ||= "Bozhidar"
* Don't use `||=` to initialize boolean variables. (Consider what
would happen if the current value happened to be `false`.)
+ [[link](#no-memoization-for-boolean)]
``` ruby
# bad - would set enabled to true even if it was false
@@ -746,22 +872,10 @@ enabled = true if enabled.nil?
etc. ). They are quite cryptic and their use in anything but
one-liner scripts is discouraged. Prefer long form versions such as
`$PROGRAM_NAME`.
-
-* 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)`.
+ [[link](#no-cryptic-vars)]
* Use `_` for unused block parameters.
+ [[link](#underscore-unused-vars)]
``` ruby
# bad
@@ -775,5 +889,8 @@ result = hash.map { |_, v| v + 1 }
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.
+ [[link](#type-checking-is-a-kind-of)]
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
\ No newline at end of file