diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md index 5683923..b294075 100644 --- a/STYLEGUIDE.md +++ b/STYLEGUIDE.md @@ -37,9 +37,11 @@ This is GitHub's Ruby Style Guide, inspired by [RuboCop's guide][rubocop-guide]. * Use soft-tabs with a two space indent. [[link](#default-indentation)] + * RuboCop rule: Layout/IndentationStyle * Indent `when` with the start of the `case` expression. [[link](#indent-when-as-start-of-case)] + * RuboCop rule: Layout/CaseIndentation ``` ruby # bad @@ -83,10 +85,18 @@ end * Never leave trailing whitespace. [[link](#trailing-whitespace)] + * RuboCop rule: Layout/TrailingWhitespace * Use spaces around operators, after commas, colons and semicolons, around `{` and before `}`. [[link](#spaces-operators)] + * RuboCop rule: Layout/SpaceAroundOperators + * RuboCop rule: Layout/SpaceAfterComma + * RuboCop rule: Layout/SpaceAfterColon + * RuboCop rule: Layout/SpaceBeforeBlockBraces + * RuboCop rule: Layout/SpaceInsideHashLiteralBraces + * RuboCop rule: Style/HashSyntax + * RuboCop rule: Layout/SpaceAroundOperators ``` ruby sum = 1 + 2 @@ -97,6 +107,8 @@ a, b = 1, 2 * No spaces after `(`, `[` or before `]`, `)`. [[link](#no-spaces-braces)] + * RuboCop rule: Layout/SpaceInsideParens + * RuboCop rule: Layout/SpaceInsideReferenceBrackets ``` ruby some(arg).other @@ -105,6 +117,7 @@ some(arg).other * No spaces after `!`. [[link](#no-spaces-bang)] + * RuboCop rule: Layout/SpaceAfterNot ``` ruby !array.include?(element) @@ -114,10 +127,12 @@ some(arg).other * End each file with a [newline](https://github.com/bbatsov/ruby-style-guide#newline-eof). [[link](#newline-eof)] + * RuboCop rule: Layout/TrailingEmptyLines * Use empty lines between `def`s and to break up a method into logical paragraphs. [[link](#empty-lines-def)] + * RuboCop rule: Layout/EmptyLineBetweenDefs ``` ruby def some_method @@ -137,12 +152,14 @@ end * 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)] + * RuboCop rule: Layout/LineLength ## Classes * Avoid the usage of class (`@@`) variables due to their unusual behavior in inheritance. [[link](#class-variables)] + * RuboCop rule: Style/ClassVars ``` ruby class Parent @@ -167,6 +184,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)] + * RuboCop rule: Style/ClassMethodsDefinitions ``` ruby class TestClass @@ -184,6 +202,7 @@ class TestClass * Avoid `class << self` except when necessary, e.g. single accessors and aliased attributes. [[link](#class-method-definitions)] + * RuboCop rule: Style/ClassMethodsDefinitions ``` ruby class TestClass @@ -217,6 +236,8 @@ 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)] + * RuboCop rule: Layout/AccessModifierIndentation + * RuboCop rule: Layout/EmptyLinesAroundAccessModifier ``` ruby class SomeClass @@ -234,6 +255,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)] + * RuboCop rule: Style/RedundantSelf ``` ruby class SomeClass @@ -251,6 +273,7 @@ end * Prefer `%w` to the literal array syntax when you need an array of strings. [[link](#percent-w)] + * RuboCop rule: Style/WordArray ``` ruby # bad @@ -268,6 +291,7 @@ STATES = %w(draft open closed) * Use symbols instead of strings as hash keys. [[link](#symbols-as-keys)] + * RuboCop rule: Style/StringHashKeys ``` ruby # bad @@ -303,9 +327,10 @@ end 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)] + * RuboCop rule: Style/Send ``` ruby -# avoid +# avoid unless [:base, :head].include?(base_or_head) raise ArgumentError, "base_or_head must be either :base or :head" end @@ -369,6 +394,7 @@ end Use the Ruby 1.9 syntax for hash literals when all the keys are symbols: [[link](#symbols-as-hash-keys)] +* RuboCop rule: Style/StringHashKeys ``` ruby # bad @@ -399,6 +425,7 @@ 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)] +* RuboCop rule: Style/HashSyntax ``` ruby @@ -420,6 +447,7 @@ hsh = { [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)] +* RuboCop rule: Style/OptionalBooleanParameter So instead of this: @@ -447,21 +475,26 @@ remove_member(user, skip_membership_check: true) * Use `snake_case` for methods and variables. [[link](#snake-case-methods-vars)] + * RuboCop rule: Naming/SnakeCase + * RuboCop rule: Naming/VariableName * Use `CamelCase` for classes and modules. (Keep acronyms like HTTP, RFC, XML uppercase.) [[link](#camelcase-classes-modules)] + * RuboCop rule: Naming/ClassAndModuleCamelCase * Use `SCREAMING_SNAKE_CASE` for other constants. [[link](#screaming-snake-case-constants)] + * RuboCop rule: Naming/ConstantName * 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)] + * RuboCop rule: Naming/PredicateName * 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 !) + should only exist if a non-bang counterpart (method name which does NOT end with !) also exists. [[link](#dangerous-method-bang)] @@ -469,6 +502,7 @@ remove_member(user, skip_membership_check: true) * Use `%w` freely. [[link](#use-percent-w-freely)] + * RuboCop rule: Style/WordArray ``` ruby STATES = %w(draft open closed) @@ -477,6 +511,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)] + * RuboCop rule: Style/BarePercentLiterals ``` ruby # bad (no interpolation needed) @@ -497,6 +532,7 @@ STATES = %w(draft open closed) * Use `%r` only for regular expressions matching *more than* one '/' character. [[link](#percent-r-regular-expressions)] + * RuboCop rule: Style/RegexpLiteral ``` ruby # bad @@ -515,7 +551,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)] - + * RuboCop rule: Lint/MixedRegexpCaptureTypes ``` ruby # bad /(regexp)/ =~ string @@ -574,6 +610,7 @@ documentation about the libraries that the current file uses. * Prefer string interpolation instead of string concatenation: [[link](#string-interpolation)] + * RuboCop rule: Style/StringConcatenation ``` ruby # bad @@ -587,6 +624,7 @@ email_with_name = "#{user.name} <#{user.email}>" will always work without a delimiter change, and `'` is a lot more common than `"` in string literals. [[link](#double-quotes)] + * RuboCop rule: Style/StringLiterals ``` ruby # bad @@ -618,6 +656,7 @@ end * Use `def` with parentheses when there are arguments. Omit the parentheses when the method doesn't accept any arguments. [[link](#method-parens-when-arguments)] + * RuboCop rule: Style/DefWithParentheses ``` ruby def some_method @@ -635,9 +674,11 @@ end always use parentheses in the method invocation. For example, write `f((3 + 2) + 1)`. [[link](#parens-no-spaces)] + * RuboCop rule: Style/MethodCallWithArgsParentheses * Never put a space between a method name and the opening parenthesis. [[link](#no-spaces-method-parens)] + * RuboCop rule: Style/ParenthesesAsGroupedExpression ``` ruby # bad @@ -653,6 +694,7 @@ f(3 + 2) + 1 * Never use `then` for multi-line `if/unless`. [[link](#no-then-for-multi-line-if-unless)] + * RuboCop rule: Style/MultilineIfThen ``` ruby # bad @@ -668,10 +710,12 @@ end * The `and` and `or` keywords are banned. It's just not worth it. Always use `&&` and `||` instead. [[link](#no-and-or-or)] + * RuboCop rule: Style/AndOr * Favor modifier `if/unless` usage when you have a single-line body. [[link](#favor-modifier-if-unless)] + * RuboCop rule: Style/MultilineTernaryOperator ``` ruby # bad @@ -685,6 +729,7 @@ do_something if some_condition * Never use `unless` with `else`. Rewrite these with the positive case first. [[link](#no-else-with-unless)] + * RuboCop rule: Style/UnlessElse ``` ruby # bad @@ -704,6 +749,7 @@ end * Don't use parentheses around the condition of an `if/unless/while`. [[link](#no-parens-if-unless-while)] + * RuboCop rule: Style/ParenthesesAroundCondition ``` ruby # bad @@ -723,6 +769,7 @@ end trivial. However, do use the ternary operator(`?:`) over `if/then/else/end` constructs for single line conditionals. [[link](#trivial-ternary)] + * RuboCop rule: Style/MultilineTernaryOperator ``` ruby # bad @@ -734,11 +781,13 @@ result = some_condition ? something : something_else * Avoid multi-line `?:` (the ternary operator), use `if/unless` instead. [[link](#no-multiline-ternary)] + * RuboCop rule: Style/MultilineTernaryOperator * 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)] + * RuboCop rule: Style/NestedTernaryOperator ``` ruby # bad @@ -760,6 +809,7 @@ end doesn't introduce a new scope (unlike `each`) and variables defined in its block will be visible outside it. [[link](#avoid-for)] + * RuboCop rule: Style/For ``` ruby arr = [1, 2, 3] @@ -779,6 +829,7 @@ arr.each { |elem| puts elem } definitions" (e.g. in Rakefiles and certain DSLs). Avoid `do...end` when chaining. [[link](#squiggly-braces)] + * RuboCop rule: Style/BlockDelimiters ``` ruby names = ["Bozhidar", "Steve", "Sarah"] @@ -801,11 +852,12 @@ 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 + 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. [[link](#avoid-return)] + * RuboCop rule: Style/RedundantReturn ``` ruby # bad @@ -821,6 +873,7 @@ end * Use spaces around the `=` operator when assigning default values to method parameters: [[link](#spaces-around-equals)] + * RuboCop rule: Style/SpaceAroundEqualsInParameterDefault ``` ruby # bad @@ -853,6 +906,7 @@ if (v = next_value) == "hello" ... * Use `||=` freely to initialize variables. [[link](#memoize-away)] + * RuboCop rule: Style/OrAssignment ``` ruby # set name to Bozhidar, only if it's nil or false @@ -862,6 +916,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)] + * RuboCop rule: Style/OrAssignment ``` ruby # bad - would set enabled to true even if it was false @@ -876,9 +931,11 @@ enabled = true if enabled.nil? one-liner scripts is discouraged. Prefer long form versions such as `$PROGRAM_NAME`. [[link](#no-cryptic-vars)] + * RuboCop rule: Style/SpecialGlobalVars * Use `_` for unused block parameters. [[link](#underscore-unused-vars)] + * RuboCop rule: Style/UnusedBlockArgument ``` ruby # bad @@ -893,6 +950,7 @@ result = hash.map { |_, v| v + 1 } 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)] + * RuboCop rule: Style/CaseEquality Refactoring is even better. It's worth looking hard at any code that explicitly checks types.