Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
R

reek

> 开发工具
Open source

Code smell detector for Ruby

4.1K stars0 likes1 views
WebsiteGitHub

About

Code smell detector for Ruby

Code smell detector for Ruby

Table of Contents

  • Overview
  • Quickstart
  • Example
  • Supported Ruby versions
  • Fixing Smell Warnings
  • Sources
  • Code smells
  • Configuration
    • Command-line interface
    • Configuration file
      • Configuration loading
      • Configuration options
    • Generating a 'todo' list
    • Beware of multiple configuration files
    • Source code comments
  • Usage
  • Developing Reek / Contributing
  • Output formats
  • Working with Rails
  • Integrations
    • Editor integrations
    • Projects that use or support us
    • Misc
  • Brothers and sisters
  • Contributors
  • Additional resources
    • Miscellaneous
    • More information

Overview

Quickstart

Reek is a tool that examines Ruby classes, modules and methods and reports any Code Smells it finds.

For an excellent introduction to Code Smells and Reek check out this blog post or that one. There is also this talk from RubyConfBY (there is also a slide deck if you prefer that).

Install it via rubygems:

gem install reek

and run it like this:

reek [options] [dir_or_source_file]*

Example

Imagine a source file demo.rb containing:

# Smelly class
class Smelly
  # This will reek of UncommunicativeMethodName
  def x
    y = 10 # This will reek of UncommunicativeVariableName
  end
end

Reek will report the following code smells in this file:

$ reek --no-documentation demo.rb
Inspecting 1 file(s):
S

demo.rb -- 2 warnings:
  [4]:UncommunicativeMethodName: Smelly#x has the name 'x'
  [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'

Supported Ruby versions

Reek is officially supported for CRuby 3.0 through 3.3 and for JRuby 9.4. Other Ruby implementations (like Rubinius) are not officially supported but should work as well.

Note that, on each Ruby version, Reek will use the parser for that version of Ruby. So, you should always run Reek using one of your project's target Ruby versions.

Fixing Smell Warnings

Reek focuses on high-level code smells, so we can't tell you how to fix warnings in a generic fashion; this is and will always be completely dependent on your domain language and business logic.

That said, an example might help you get going. Have a look at this sample of a Ruby on Rails model (be aware that this is truncated, not working code):

class ShoppingCart < ActiveRecord::Base
  has_many :items

  def gross_price
    items.sum { |item| item.net + item.tax }
  end
end

class Item < ActiveRecord::Base
  belongs_to :shopping_cart
end

Running Reek on this file like this:

reek app/models/shopping_cart.rb

would report:

  [5, 5]:ShoppingCart#gross_price refers to item more than self (FeatureEnvy)

Fixing this is pretty straightforward. Put the gross price calculation for a single item where it belongs, which would be the Item class:

class ShoppingCart < ActiveRecord::Base
  has_many :items

  def gross_price
    items.sum { |item| item.gross_price }
  end
end

class Item < ActiveRecord::Base
  belongs_to :shopping_cart

  def gross_price
    net + tax
  end
end

The Code Smells docs may give you further hints - be sure to check out those first when you have a warning that you don't know how to deal with.

Sources

There are multiple ways you can have Reek work on sources, the most common one just being

reek lib/

If you don't pass any source arguments to Reek it just takes the current working directory as source.

So

reek

is the exact same thing as being explicit:

reek .

Additionally you can pipe code to Reek like this:

echo "class C; def m; end; end" | reek

This would print out:

$stdin -- 3 warnings:
  [1]:C has no descriptive comment (IrresponsibleModule)
  [1]:C has the name 'C' (UncommunicativeModuleName)
  [1]:C#m has the name 'm' (UncommunicativeMethodName)

Code smells

Reek currently includes checks for some aspects of Control Couple, Data Clump, Feature Envy, Large Class, Long Parameter List, Simulated Polymorphism, Too Many Statements, Uncommunicative Name, Unused Parameters and more. See the Code Smells for up to date details of exactly what Reek will check in your code.

Special configuration for controversial detectors:

Unused Private Method is disabled by default because it is kind of controversial which means you have to explicitly activate it in your configuration via

UnusedPrivateMethod:
  enabled: true

Utility Function is a controversial detector as well that can turn out to be really unforgiving. As a consequence, we made it possible to disable it for non-public methods like this:

---
UtilityFunction:
  public_methods_only: true

Configuration

Command-line interface

For a basic overview, run

reek --help

For a summary of those CLI options see Command-Line Options.

Configuration file

Configuration loading

Configuring Reek via a configuration file is by far the most powerful way. Reek expects this filename to be .reek.yml but you can override this via the CLI -c switch (see below).

There are three ways of passing Reek the configuration file:

  1. Using the CLI -c switch (see Command-line interface above)
  2. Having the configuration file either in your current working directory or in a parent directory (more on that later)
  3. Having the configuration file in your home directory

The order in which Reek tries to find such a configuration file is exactly the above: first it checks if we have given it a configuration file explicitly via CLI; then it checks the current working directory for a file and if it can't find one, it traverses up the directories until it hits the root directory; lastly, it checks your home directory.

As soon as Reek detects a configuration file it stops searching immediately, meaning that from Reek's point of view there exists exactly one configuration file and one configuration, regardless of how many *.reek files you might have on your filesystem.

Configuration options

We put a lot of effort into making Reek's configuration as self explanatory as possible so the best way to understand it is by looking at a simple example (e.g. .reek.yml in your project directory):

…

As you see above, Reek's configuration consists of 3 different sections denoted by 3 different keys:

  • detectors
  • directories
  • exclude_paths

Whatever you add to your configuration should be scoped under one of those keys.

If you have a directory directive for which a default directive exists, the more specific one (which is the directory directive) will take precedence.

This configuration for instance:

---
detectors:
  IrresponsibleModule:
    enabled: false

  TooManyStatements:
    max_statements: 5

directories:
  "app/controllers":
    TooManyStatements:
      max_statements: 10

translates to:

  • IrresponsibleModule is disabled everywhere
  • TooManyStatements#max_statements is 10 in "app/controllers"
  • TooManyStatements#max_statements is 5 everywhere else

Every smell detector supports our Basic Smell Options. As you can see above, certain smell types offer a configuration that goes beyond that of the basic smell options, for instance Data Clump. All options that go beyond the Basic Smell Options are documented in the corresponding smell type /docs page (if you want to get a quick overview over all possible configurations you can also check out the defaults.reek.yml file in this repository.

Note that you do not need a configuration file at all. If you're fine with all the defaults we set you can skip this completely.

Don't worry about introducing a mistake in your configuration file that might go unnoticed - Reek uses a schema to validate your configuration against on start up and will faily loudly in case you misspelled an option or used the wrong data type for a value like this:

Error: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.

Reek takes one configuration file and one configuration file only with .reek.yml being the default name.

In case you have to have one or more configuration files in the directory (e.g. you're toying around with different, mutually exclusive settings) you need to tell Reek explicitly which file to use via reek -c config.reek.

Source code comments

In case you need to suppress a smell warning and you can't or don't want to use configuration files for whatever reasons you can also use special source code comments like this:

# This method smells of :reek:NestedIterators
def smelly_method foo
  foo.each {|bar| bar.each {|baz| baz.qux}}
end

You can even pass in smell specific configuration settings:

# :reek:NestedIterators { max_allowed_nesting: 2 }
def smelly_method foo
  foo.each {|bar| bar.each {|baz| baz.qux}}
end

This is an incredibly powerful feature and further explained under Smell Suppression.

Debugging trouble with the configuration

With Reeks dynamic mechanism of finding a configuration file you might run into a situation where you are not 100% sure what configuration file Reek is using. E.g. you have a project specific configuration file in your project root and also another Reek configuration in your HOME directory that you use for all your other projects and for whatever reasons Reek seems to be using another configuration file than the one you assumed it would.

In this case you can pass the flag --show-configuration-path to Reek which will cause Reek to output the path to the configuration file it is using.

Generating a 'todo' list

Integrating tools like Reek into an existing larger codebase can be daunting when you have to fix possibly hundreds or thousands of smell warnings first. Sure you could manually disable smell warnings like shown above but depending on the size of your codebase this might not be an option. Fortunately Reek provides a 'todo' flag which you can use to generate a configuration that will suppress all smell warnings for the current codebase:

reek --todo lib/

This will create the file '.reek.yml' in your current working directory.

You can then use this as your configuration - since you

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Rubylintersparsingqualityruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category开发工具
PricingOpen source

> Related tools

V
VS Code
流行的开源代码编辑器
G
Git
分布式版本控制系统
V
Vite
下一代前端构建工具