My Ruby Style

Published: November 24, 2020

This is part of The Annotated Guide to a New Rails App, 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.

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.

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.

require: rubocop-rails

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

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/**/*

A combination of clear naming and RSpec specifications obviates the need for class documentation blocks.

Style/Documentation:
Enabled: false

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
Layout/FirstArrayElementIndentation:
EnforcedStyle: consistent

Implicit hashes do not need to be formatted like hashes.

Layout/HashAlignment:
EnforcedLastArgumentHashStyle: ignore_implicit

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*# '

Similar to argument alignment, the default setting with_first_parameter wastes too much space.

Layout/ParameterAlignment:
EnforcedStyle: with_fixed_indentation

Writing idiomatic RSpec requires violating this rule, so we exclude RSpec files from it.

Lint/AmbiguousBlockAssociation:
Exclude:
- "**/*_spec.rb"

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"

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"

Use doend 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 methods are unlikely to stay empty, so let’s make it easy to edit them.

def empty_method
end
Style/EmptyMethod:
EnforcedStyle: expanded

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 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

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

Engineering leader with twenty years of experience in software startups