skip to content

RuboCop

RuboCop checks Ruby code against configurable cops grouped into departments, autocorrects offences safely or unsafely, and underpins the zero-config Standard. Interviewers probe how teams adopt it.

on this pageshow

explore

questions

18

In a .rubocop.yml file, how do you disable a cop, change one of its options and exclude files, and what is a department?

level: juniorimportance: must knowfreq 65%

answer

  1. Department/CopName as the YAML key
  2. Enabled: false under the cop
  3. options such as Max or EnforcedStyle
  4. AllCops Exclude vs a cop's own Exclude
  5. --show-cops prints the effective settings

basics

~20 s

A .rubocop.yml keys each cop by qualified name, such as Layout/LineLength: Enabled: false switches it off, keys like Max tune it, and Exclude skips paths. A department (Lint, Style, Layout, Metrics...) groups cops and can be configured as one.

solid answer

~40 s

RuboCop starts from the defaults in its own `config/default.yml`; `.rubocop.yml` only lists the differences. Each cop is keyed by its qualified name, `Department/CopName`. Under it, `Enabled: false` turns the cop off, cop-specific options tune it (`Layout/LineLength: Max: 100`, `Style/StringLiterals: EnforcedStyle: double_quotes`), and `Exclude` lists paths that one cop skips. `AllCops: Exclude` skips paths for every cop. A **department** is the prefix: `Lint`, `Style`, `Layout`, `Metrics`, `Naming`, `Security`, `Bundler`, `Gemspec`, `Migration`. A department key such as `Metrics: Enabled: false` switches the whole group off, and a single cop inside it can still be turned back on with its own `Enabled: true`. A misspelled cop name stops the run with an `unrecognized cop or department` error, and `rubocop --show-cops Layout/LineLength` prints what actually applies.

code

yaml · 20 lines
yaml
# .rubocop.yml
AllCops:
  Exclude:
    - "db/schema.rb"
    - "bin/**/*"
    - "vendor/**/*"   # repeated: this list replaces the default one

Style/StringLiterals:
  EnforcedStyle: double_quotes

Layout/LineLength:
  Max: 100
  Exclude:
    - "config/routes.rb"

Metrics:
  Enabled: false

Metrics/CyclomaticComplexity:
  Enabled: true

go deeper

for a junior

Recall the Department/CopName key, Enabled: false, one option such as Max or EnforcedStyle, and the difference between AllCops Exclude and a cop's own Exclude.

for a middle

Explain that the file only overrides config/default.yml, that the nearest .rubocop.yml wins for a file, and that a list you write replaces the inherited list.

for a senior

Show how you verify a config instead of guessing: --show-cops for effective settings, -L for the file set, and --force-exclusion for tools that pass files by name.

for a principal

Treat .rubocop.yml as a reviewed policy file: every disabled cop or raised Max is a team decision that should carry a comment saying why.

## What the file is **RuboCop** is a static code analyser and formatter for Ruby. Each individual check is a **cop**, and every cop ships with default settings in the gem's own `config/default.yml`. A project's **`.rubocop.yml`** is a YAML file that lists only the settings that differ from those defaults; everything you do not mention keeps its default value. RuboCop picks the configuration for a file by looking for the **nearest** `.rubocop.yml`, starting in the inspected file's directory and walking upwards. If none is found in the project it falls back to `.config/.rubocop.yml` at the project root, then `~/.rubocop.yml`, then `~/.config/rubocop/config.yml`, and finally the built-in defaults. Passing `--config FILE` on the command line replaces that search with one explicit file. ## Departments and cop names Every cop has a **qualified name** of the form `Department/CopName`, and that name is the YAML key you configure it under. The **department** is the group the cop belongs to. RuboCop 1.91 itself ships nine: | Department | What its cops look at | Default severity | |---|---|---| | `Lint` | likely bugs and ambiguous code | `warning` | | `Security` | dangerous calls such as `eval` with dynamic input | `warning` | | `Metrics` | size and complexity (method length, ABC size) | `refactor` | | `Layout` | whitespace, indentation, alignment, line length | `convention` | | `Style` | idiom and consistency choices | `convention` | | `Naming` | names of methods, variables, constants, files | `convention` | | `Bundler` | the `Gemfile` | `convention` | | `Gemspec` | `*.gemspec` files | `convention` | | `Migration` | department-qualified cop names in `rubocop:` directive comments | `convention` | A few cops override their department's severity; `Bundler/DuplicatedGem`, for example, reports at `warning`. Extension gems add their own departments (for example `Performance` from rubocop-performance). Writing the bare cop name without its department still works when the name is unique, but the qualified form is the recommended one. ## The keys you set under a cop - **`Enabled`** - `true` or `false`. A few cops ship disabled; newly added cops ship with the special value `pending` until you decide. - **Cop-specific options** - each cop documents its own: `Max` for `Layout/LineLength` and the `Metrics` cops, `EnforcedStyle` for style choices such as `Style/StringLiterals` (default `single_quotes`), `AllowedMethods` and `AllowedPatterns` for exemptions. - **`Include` / `Exclude`** - path globs this one cop inspects or skips. - **`Severity`** - the level the cop's offenses are reported at (`info`, `refactor`, `convention`, `warning`, `error`, `fatal`). - **`AutoCorrect`** - `always`, `contextual` or `disabled`, which limits whether the cop may rewrite code. A **department key** accepts the same common settings for all its cops at once. Precedence works in the cop's favour: 1. `Style: Enabled: false` turns every `Style` cop off. 2. `Style/Alias: Enabled: true` in the same file (or a file inheriting from it) turns that one cop back on. 3. Every other `Style` cop stays off. ## Excluding files - **`AllCops: Exclude`** removes paths from inspection for every cop. The default list is `node_modules/**/*`, `tmp/**/*`, `vendor/**/*` and `.git/**/*`. - **A cop's own `Exclude`** removes paths for that cop only; other cops still inspect the file. - A list you write **replaces** the list it inherits, so an `AllCops: Exclude` that names only `db/schema.rb` drops the `vendor/**/*` default unless you repeat it. - Paths in `.rubocop.yml` are relative to the directory the file sits in. - Files passed **explicitly** on the command line are inspected even when excluded; `--force-exclusion` makes RuboCop honour `Exclude` for them too, which matters for editor and pre-commit integrations that pass single files. ## Checking what you configured - `rubocop --show-cops Layout/LineLength` prints the cop's effective settings for the current directory, after all inheritance. - `rubocop -L` (`--list-target-files`) lists the files a run will inspect, which is the quickest way to test an `Exclude` glob. - `rubocop --list-enabled-cops-for app/models` lists the cops that will run on a path. - A key that is not a known cop or department makes the run fail with `unrecognized cop or department ... found in .rubocop.yml`; `--ignore-unrecognized-cops` turns that into a warning. - `Lint/Syntax` is the one cop you cannot configure: any setting for it is rejected, because it reports files that do not parse.

  • What happens when a .rubocop.yml misspells a cop name, for example Layout/LineLenght?
    RuboCop validates the configuration before inspecting anything and stops with `unrecognized cop or department Layout/LineLenght found in .rubocop.yml`, so the typo fails the run instead of being silently ignored. `--ignore-unrecognized-cops` downgrades the error to a warning, which helps when one shared file is read by several RuboCop versions and a newer cop does not exist in the older one yet.
  • Why does a pre-commit hook report offenses in a file that AllCops Exclude lists?
    The hook passes changed files to `rubocop` by name, and RuboCop inspects files given explicitly on the command line even when they match `AllCops: Exclude`. Adding `--force-exclusion` to the hook's command makes RuboCop apply the `Exclude` patterns to explicit arguments as well, so generated or vendored files stay skipped.

saying these in an interview costs you the question

  • A misspelled cop name in .rubocop.yml is silently ignored.
  • Disabling a department means no cop in it can be switched back on.
  • A cop's own Exclude list also stops every other cop from inspecting that file.
  • RuboCop only reads the .rubocop.yml at the project root, never one in a subdirectory.
  • Lint/Syntax can be disabled in .rubocop.yml like any other cop.
open as a page

What is Standard Ruby (the standard gem), how do you run it with standardrb or rake standard, and how does it differ from configuring RuboCop yourself?

level: juniorimportance: must knowfreq 55%

basics

~20 s

Standard Ruby is a gem that runs RuboCop with a fixed, non-configurable ruleset. Run standardrb (or rake standard after requiring standard/rake), add --fix for safe corrections; it ignores .rubocop.yml and reads only options from .standard.yml.

open as a page

In RuboCop, what is the difference between rubocop -a and rubocop -A, and how do a cop's Safe and SafeAutoCorrect settings decide what -a changes?

level: middleimportance: must knowfreq 70%

basics

~20 s

rubocop -a applies only corrections RuboCop marks safe; rubocop -A also applies unsafe ones that may change behaviour. A correction counts as safe only when the cop has both Safe and SafeAutoCorrect true, which is the default.

open as a page

In Ruby code checked by RuboCop, how do rubocop:disable, rubocop:enable and rubocop:todo comments work, and how do you keep them tightly scoped?

level: middleimportance: must knowfreq 65%

basics

~20 s

A # rubocop:disable Cop comment at the end of a line silences that line; on its own line it silences until # rubocop:enable Cop. rubocop:todo is an alias marking a suppression to revisit. -- reason documents why.

open as a page

In RuboCop, how do you share one .rubocop.yml style across many repositories with inherit_gem or inherit_from, and which setting wins on conflict?

level: middleimportance: must knowfreq 50%

basics

~20 s

Publish the shared file in a gem and load it with inherit_gem, or point inherit_from at a path or URL. inherit_gem files load first, then inherit_from files in list order (last wins), and the repository's own settings override both.

open as a page

How do you make RuboCop run, or autocorrect, just one cop or department with --only, and skip cops with --except?

level: juniorimportance: should knowfreq 40%

basics

~10 s

Pass a comma-separated list: rubocop --only Layout/LineLength,Style/StringLiterals runs just those, --only Lint a department, and --except Metrics runs everything else. Add -a to autocorrect only that selection.

open as a page

In a .rubocop.yml, why can adding one AllCops Exclude pattern make RuboCop inspect vendor/, and how does inherit_mode prevent it?

level: middleimportance: should knowfreq 35%

basics

~10 s

Array settings such as Exclude replace the inherited array, so a one-entry AllCops Exclude drops the default vendor/**/* pattern. inherit_mode: merge: [Exclude] unions the lists instead, globally or for one cop.

open as a page

In RuboCop, what does AllCops TargetRubyVersion change, and where does RuboCop find the version when .rubocop.yml does not set it?

level: middleimportance: should knowfreq 40%

basics

~10 s

TargetRubyVersion tells RuboCop the oldest Ruby the code must run on; it selects the parser grammar and which version-gated cops apply. Unset, RuboCop reads the gemspec, .ruby-version, mise.toml, .tool-versions or Gemfile.lock, else assumes 2.7.

open as a page

In Standard Ruby, what is the difference between standardrb --fix, --fix-unsafely and --no-fix, and how do you make fixing the default?

level: middleimportance: should knowfreq 35%

basics

~10 s

standardrb --fix applies only corrections RuboCop marks safe; --fix-unsafely also applies unsafe ones that can change behaviour. fix: true in .standard.yml makes fixing the default, and --no-fix turns it off for one run.

open as a page

When adopting Standard Ruby on an existing codebase, what does standardrb --generate-todo produce, and how do standard:disable comments work?

level: middleimportance: should knowfreq 30%

basics

~20 s

standardrb --generate-todo writes .standard_todo.yml, mapping each file that has offenses to the cops it violates; Standard then ignores those, warns about them, and still checks everything else. # standard:disable Cop comments silence specific lines like RuboCop's own directives.

open as a page

In a .standard.yml file, what do ignore, default_ignores and ruby_version control, and what does Standard assume when ruby_version is missing?

level: middleimportance: should knowfreq 35%

basics

~20 s

ignore skips paths, or only named cops for a path; default_ignores (true by default) adds Standard's own skips such as vendor/**/, bin/ and db/schema.rb. ruby_version sets RuboCop's target; without it Standard uses the Ruby running standardrb.

open as a page

After a one-off rubocop -A run on a Ruby 4.0 app, tests fail with FrozenError and NoMethodError; what did the run change, and how should it have been done?

level: seniorimportance: should knowfreq 35%

basics

~20 s

rubocop -A applied corrections marked unsafe: the frozen-string-literal comment froze mutated literals (FrozenError), and x && x.foo became x&.foo, which breaks when x is false. Run -a first, then -A one cop at a time with tests between.

open as a page

In RuboCop, what does rubocop --auto-gen-config write into .rubocop_todo.yml, and how do you keep that todo file shrinking instead of rotting?

level: seniorimportance: should knowfreq 50%

basics

~20 s

--auto-gen-config writes .rubocop_todo.yml, which excludes each offending file per cop (up to 15, then disables the cop) or raises Metrics Max values, and links it via inherit_from. Delete entries as you fix code; --report-unused-todo-entries fails on stale ones.

open as a page

After a RuboCop upgrade, a run warns about pending cops and about `require: rubocop-performance` - what does each warning mean, and how do you fix the .rubocop.yml?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Pending cops are new cops that stay off until you decide; set each one's Enabled, or NewCops for all or per department. The require: warning means the gem is now a plugin, so list it under plugins: instead.

open as a page

How do you add rules to Standard Ruby with plugins or extend_config in .standard.yml, and why can neither change Standard's own rules?

level: seniorimportance: should knowfreq 25%

basics

~20 s

List lint_roller plugin gems such as standard-rails under plugins:, or RuboCop YAML files under extend_config:. Configuration is first-in-wins: Standard's built-in plugins load first, so later plugins and files can add cops but never reconfigure ones already set.

open as a page

Adopting RuboCop on a five-year-old Ruby codebase, how do you decide which departments and cops the team enforces, and how do you encode that in .rubocop.yml?

level: principalimportance: should knowfreq 25%

basics

~20 s

Enforce what prevents bugs first: Lint and Security fail the build; Layout is autocorrected once; Style and Metrics are chosen deliberately. Encode it with department and cop Enabled, Severity, AllCops FailLevel and, for a strict opt-in list, DisabledByDefault.

open as a page

Why is RuboCop slow when an editor or git hook runs it per file, and what do its --server mode and --lsp language server change?

level: middleimportance: nice to knowfreq 25%

basics

~20 s

Each rubocop invocation spends much of its time loading RuboCop and its plugins. --server keeps a background process with everything loaded and forwards later commands to it; --lsp runs a long-lived language server that editors talk to directly.

open as a page

You are starting a new open-source Ruby gem that supports Ruby 3.2 and later: how would you set up Standard, and when would plain RuboCop be the better choice?

level: seniorimportance: nice to knowfreq 20%

basics

~20 s

Put standard in the Gemfile's development group, set ruby_version: 3.2 in .standard.yml, and make rake's default task run tests and standard. Choose plain RuboCop to tune cops, enforce Metrics, or use features newer than Standard's pinned RuboCop.

open as a page