My Ruby Style
Published: Nov 24th, 2020
Updated: Dec 30th, 2020
This is part of Joyful Rails, a list of recommendations to make developing your Rails app more productive and joyful.
In this article, we are going to talk about my Ruby style.
Background
This is my Ruby style. It is not right or wrong. It is a collection of personal preferences reflecting my values and trade-offs.
Your Ruby style may be different. Decisions on coding style should reflect the environment and preferences of the people reading and writing the code.
About this article
I am going to be describing my Ruby style as a collection of configuration settings to RuboCop.
If you agree with me, you can add the settings below to your Rubocop configuration.
Use Rails cops
require: rubocop-rails
Enable new cops
New cops are added all the time and by default are pending until the next major release. Enable them automatically so you can more easily stay up to date.
AllCops:
NewCops: enable
Global exclusion
Exclude generated files from RuboCop enforcement. I don’t write, read, or edit these files so I don’t care about their style.
AllCops:
Exclude:
- bin/*
- config.ru
- db/schema.rb
- node_modules/**/*
Documentation
A combination of clear naming and RSpec specifications obviates the need for class documentation blocks.
Style/Documentation:
Enabled: false
Argument Alignment
The default style, with_first_argument
, wastes too much space.
method_name(:first_arg
:second_arg)
with_fixed_indentation
is great for methods with a lot of arguments.
method_with_a_long_name(:first, :second, :third,
:forth, :fifth, :sixth, :seventh, :eigth)
Layout/ArgumentAlignment:
EnforcedStyle: with_fixed_indentation
First Array Element Indentation
Layout/FirstArrayElementIndentation:
EnforcedStyle: consistent
Hash Alignment
Implicit hashes do not need to be formatted like hashes.
Layout/HashAlignment:
EnforcedLastArgumentHashStyle: ignore_implicit
Line Length
Cop directives should not need to be under our line length requirements. This makes it much easer to apply a cop directive to a single line of code.
Layout/LineLength:
IgnoreCopDirectives: true
Allow comments to be really long. A lot of the boilerplate comments generated by Rails are over 80 characters. With this, you won’t need to fix them or delete them.
Layout/LineLength:
IgnoredPatterns:
- '^\s*# '
Parameter Alignment
Similar to argument alignment, the default setting with_first_parameter
wastes
too much space.
Layout/ParameterAlignment:
EnforcedStyle: with_fixed_indentation
Ambiguous Block Association
Writing idiomatic RSpec requires violating this rule, so we exclude RSpec files from it.
Lint/AmbiguousBlockAssociation:
Exclude:
- "**/*_spec.rb"
Block Length
Idiomatic RSpec often has very long blocks. There is no harm in configuration files having long blocks. So we exclude both of those.
Metrics/BlockLength:
Exclude:
- Guardfile
- config/environments/*
- config/routes.rb
- "**/*_spec.rb"
Method Length
It usually isn’t helpful to break up migration methods, so we allow them to get as long as they need.
Metrics/MethodLength:
Exclude:
- "db/migrate/*.rb"
Block Delimiters
Use do
…end
for a multiline block, unless you are chaining.
words.each do |word|
puts word
end
puts words.each { |word|
word.flip.flop
}.join("\n")
Style/BlockDelimiters:
EnforcedStyle: braces_for_chaining
Empty Method
Empty methods are unlikely to stay empty, so let’s make it easy to edit them.
def empty_method
end
Style/EmptyMethod:
EnforcedStyle: expanded
Frozen String Literal Comment
The eventual transition to frozen string literals will not be difficult for a codebase with good specs. There is no need to clutter up our files trying to prepare for it.
Style/FrozenStringLiteralComment:
Enabled: false
String Literals
String literals should be double-quoted when interpolated, when they include a single-quote character, or when they are natural language texts.
Natural language strings often use single quotes as apostrophes for contractions and possessives. Using double quotes means being able to change the text, including adding or removing apostrophes, without having to alter the quote characters.
For this reason, we exclude Ruby files that are likely to contain natural language text strings.
Style/StringLiterals:
Exclude:
- lib/tasks/*.rake
- spec/**/*_spec.rb
Trailing Commas
Including trailing commas in arguments, array literals, and hash literals makes it easier to add, remove, and reorder items.
As a bonus, it makes it easier to read Git commits because changing one item only changes one line in the file.
Style/TrailingCommaInArguments:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: comma