
目次

Reekは、Rubyクラス、モジュール、メソッドを調べ、コードの臭いをレポートするツールです。
コードの匂いとreekの優れた紹介については、このブログ投稿などをご覧ください。 Rubyconfbyからのこの講演もあります(それを好むなら、スライドデッキもあります)。
Rubygems経由でそれをインストールします:
gem install reekそして、このように実行します:
reek [options] [dir_or_source_file] * ソースファイルを想像してくださいdemo.rbを含む:
# Smelly class
class Smelly
# This will reek of UncommunicativeMethodName
def x
y = 10 # This will reek of UncommunicativeVariableName
end
endReekは、このファイルで次のコードの匂いを報告します。
$ 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'
Reekは、Cruby 3.0から3.3、Jruby 9.4で正式にサポートされています。他のRubyの実装(Rubiniusなど)は公式にはサポートされていませんが、同様に機能するはずです。
各Rubyバージョンでは、ReekはRubyのバージョンにパーサーを使用することに注意してください。したがって、プロジェクトのターゲットRubyバージョンの1つを使用して、常にReekを実行する必要があります。
Reekは高レベルのコードの匂いに焦点を当てているので、一般的な方法で警告を修正する方法を説明することはできません。これは、常にドメイン言語とビジネスロジックに完全に依存します。
とはいえ、例はあなたが進むのに役立つかもしれません。 Ruby on Railsモデルのこのサンプルをご覧ください(これは、動作していないコードではなく切り捨てられていることに注意してください):
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このようにこのファイルでREEKを実行してください:
reek app/models/shopping_cart.rb
報告します:
[5, 5]:ShoppingCart#gross_price refers to item more than self (FeatureEnvy)
これを修正することは非常に簡単です。総価格計算を属する単一のアイテムの総価格計算を入れてください。これはItemクラスになります。
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コードの匂いは、ドキュメントがさらにヒントを与えるかもしれません - あなたが対処方法がわからないという警告があるときは、最初にそれらをチェックしてください。
ソースでreekの作業を行うことができる複数の方法がありますが、最も一般的なものはただです
reek lib/ソース引数を渡さない場合は、現在の作業ディレクトリをソースとして取得します。
それで
reek明示的であることとまったく同じことです:
reek .さらに、このようにreekするためにコードをパイプすることができます:
echo " class C; def m; end; end " | reekこれは印刷されます:
$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)現在、REEKには、コントロールカップル、データクランプ、機能のvy望、大規模クラス、長いパラメーターリスト、シミュレートされた多型、あまりにも多くのステートメント、不信心な名前、未使用のパラメーターなどのいくつかの側面のチェックが含まれています。 Reekがコードをチェックインするものの正確な詳細については、コードの匂いを参照してください。
物議を醸す検出器のための特別な構成:
未使用のプライベートメソッドはデフォルトで無効にされています。これは、ある種の議論の余地があるため、構成で明示的にアクティブ化する必要があることを意味します。
UnusedPrivateMethod :
enabled : trueユーティリティ機能は、物議を醸す検出器でもあり、本当に容赦ないことが判明する可能性があります。結果として、私たちはこのような非公開の方法でそれを無効にすることを可能にしました:
---
UtilityFunction :
public_methods_only : true 基本的な概要については、実行してください
reek -- helpこれらのCLIオプションの要約については、コマンドラインオプションを参照してください。
Configurationファイルを介してReekを構成することは、はるかに強力な方法です。 Reekは、このファイル名が.reek.ymlであることを期待していますが、CLI -cスイッチを介してこれをオーバーライドできます(以下を参照)。
構成ファイルをReekに合格するには、次の3つの方法があります。
-cスイッチの使用(上記のコマンドラインインターフェイスを参照)Reekがそのような構成ファイルを見つけようとする順序は、まさに上記です。最初に、CLIを介して明示的に構成ファイルを指定したかどうかをチェックします。次に、ファイルの現在の作業ディレクトリをチェックし、それが見つからない場合、ルートディレクトリにヒットするまでディレクトリを横断します。最後に、ホームディレクトリをチェックします。
Reekが構成ファイルを検出するとすぐに、すぐに検索を停止します。つまり、Reekの観点からは、ファイルシステムにある*.reekファイルの数に関係なく、正確に1つの構成ファイルと1つの構成が存在します。
Reekの構成を可能な限り自明にすることに多くの努力を払っているので、それを理解する最良の方法は、簡単な例を見ることです(例:プロジェクトディレクトリの.reek.yml ):
---
# ## Generic smell configuration
detectors :
# You can disable smells completely
IrresponsibleModule :
enabled : false
# You can use filters to silence Reek warnings.
# Either because you simply disagree with Reek (we are not the police) or
# because you want to fix this at a later point in time.
NestedIterators :
exclude :
- " MyWorker#self.class_method " # should be refactored
- " AnotherWorker#instance_method " # should be refactored as well
# A lot of smells allow fine tuning their configuration. You can look up all available options
# in the corresponding smell documentation in /docs. In most cases you probably can just go
# with the defaults as documented in defaults.reek.yml.
DataClump :
max_copies : 3
min_clump_size : 3
# ## Directory specific configuration
# You can configure smells on a per-directory base.
# E.g. the classic Rails case: controllers smell of NestedIterators (see /docs/Nested-Iterators.md) and
# helpers smell of UtilityFunction (see docs/Utility-Function.md)
#
# Note that we only allow configuration on a directory level, not a file level,
# so all paths have to point to directories.
# A Dir.glob pattern can be used.
directories :
" web_app/app/controllers " :
NestedIterators :
enabled : false
" web_app/app/helpers** " :
UtilityFunction :
enabled : false
" web_app/lib/**/test/** " :
UtilityFunction :
enabled : false
# ## Excluding directories
# Directories and files below will not be scanned at all
exclude_paths :
- lib/legacy
- lib/rake/legacy_tasks
- lib/smelly.rb上記のように、Reekの構成は、3つの異なるキーで示される3つの異なるセクションで構成されています。
構成に追加するものは何でも、それらのキーのいずれかの下でスコープする必要があります。
デフォルトのディレクティブが存在するディレクトリディレクティブがある場合、より具体的なディレクティブ(ディレクトリディレクティブ)が優先されます。
たとえば、この構成:
---
detectors :
IrresponsibleModule :
enabled : false
TooManyStatements :
max_statements : 5
directories :
" app/controllers " :
TooManyStatements :
max_statements : 10翻訳:
すべての臭い検出器は、基本的な臭いオプションをサポートしています。上記のように、特定の臭いタイプは、基本的な臭いオプションのそれを超える構成、たとえばデータクロンプを提供します。基本的な臭いオプションを超えるすべてのオプションは、対応する臭いタイプ /ドキュメントページに文書化されています(すべての可能な構成について簡単に概要を取得する場合は、このリポジトリのdefaults.reek.ymlファイルも確認できます。
構成ファイルはまったく必要ないことに注意してください。設定したすべてのデフォルトで問題ない場合は、これを完全にスキップできます。
気付かない可能性のある構成ファイルに間違いを導入することを心配しないでください-Reekはスキーマを使用して起動時に構成を検証します。
Error: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.
Reekは、1つの構成ファイルと1つの構成ファイルを使用して、 .reek.ymlがデフォルト名です。
ディレクトリに1つ以上の構成ファイルを使用する必要がある場合(例えば、異なる相互に排他的な設定でいじめています)、 reek -c config.reekを介して使用するファイルを明示的に伝える必要があります。
匂いの警告を抑制する必要がある場合に備えて、このような特別なソースコードコメントを使用できる理由で構成ファイルを使用することはできないか、使用したくないか:
# This method smells of :reek:NestedIterators
def smelly_method foo
foo . each { | bar | bar . each { | baz | baz . qux } }
end特定の構成設定を嗅ぐこともできます。
# :reek:NestedIterators { max_allowed_nesting: 2 }
def smelly_method foo
foo . each { | bar | bar . each { | baz | baz . qux } }
endこれは信じられないほど強力な機能であり、さらに匂いの抑制の下で説明されています。
Configurationファイルを見つけるReeks動的メカニズムを使用すると、Reekが使用している構成ファイルが100%確信していない状況に遭遇する可能性があります。たとえば、プロジェクトルートにプロジェクト固有の構成ファイルと、他のすべてのプロジェクトに使用しているホームディレクトリに、またReekが想定したものよりも別の構成ファイルを使用していると思われる別のReek構成があります。
この場合、フラグ--show-configuration-pathを渡すことができます。
Reekなどのツールを既存の大きなコードベースに統合することは、最初に数百または数千の臭い警告を修正する必要がある場合、困難な場合があります。確かに、上記のような臭いの警告を手動で無効にすることができますが、コードベースのサイズに応じて、これはオプションではないかもしれません。幸いなことに、Reekは、現在のコードベースのすべての臭い警告を抑制する構成を生成するために使用できる「TODO」フラグを提供します。
reek --todo lib/これにより、現在の作業ディレクトリにファイル '.reek.yml'が作成されます。
その後、これを構成として使用できます。作業ディレクトリはおそらくプロジェクトルートであるため、ほとんどの場合、Reekを「.reek.yml」を使用するように明示的に指示する必要はありません。上記の構成読み込みを参照してください。
何らかの理由で、 '.reek.yml' reekが自動的にそれを拾わない他の場所に置くことにした場合は、次のことを明示的に伝える必要があります。
reek -c whatever/.reek.yml lib/ --todoフラグのナンバーワンのユースケースは、遷移を容易にするためにリークの導入の開始時に一度実行されることを理解することが重要です。多くの新しい警告を沈黙させるために、 --todoフラグとリーク自体の両方の目的を打ち負かすために、 --todoフラグで再実行したいと思う場合。
結果として、 --todoフラグで再びreekを実行しても、既存の '.reek.yml'を上書きすることはなく、代わりに実行を中止します。また、考慮される可能性のある他の構成ファイルも取得しません。
これは、実行するときにそれを意味します
reek -c other_configuration.reek --todo lib/ other_configuration.reek単に無視されます。
もちろん、既存の.reek.ymlファイルをいつでも削除してから、 --todoフラグでReekを実行できますが、これはこの機能の意図したユースケースではないことに留意してください。
明白なことに加えて
reek [options] [dir_or_source_file] *プロジェクトでReekを使用する方法はかなりあります。
ソースコードをチェックした後に最初にやりたいことは、バンドラーを実行することです。
bundle install
そして、テストを実行します。
bundle exec rspec spec/your/file_spec.rb # Runs all tests in spec/your/file_spec.rb
bundle exec rspec spec/your/file_spec.rb:23 # Runs test in line 23
bundle exec cucumber features/your_file.feature # Runs all scenarios in your_file.feature
bundle exec cucumber features/your_file.feature:23 # Runs scenario at line 23または、テストスイート全体を実行するだけです。
bundle exec rake
これにより、テスト(RSPECおよびキュウリ)、RuboCop、Reek自体が実行されます。
別の便利なレーキタスクは、 consoleタスクです。これにより、Reeksモジュールとクラスで遊ぶことができる環境にすぐに投げかけます。
bundle exec rake console
irb(main):001> Reek::Examiner
=> Reek::Examiner
また、デバッグを開始するポイントで以下を追加することにより、テストの実行中にIRBを使用することもできます。
binding . irbよりインスピレーションを得るために、開発者APIをご覧ください。
それ以降、チェックアウトする必要があります。
コードで手を汚したくない場合は、私たちを助けることができる他の方法がまだあります。
コードの気候問題(例えば、コードの複製しきい値を越えて進む)に遭遇した場合は、REEKコードベースに対してローカルでコード気候を実行できるようにすることができます。これを行うには、次のことを行う必要があります。
gem install codeclimatecodeclimate engines:installこれで、さまざまなコード気候エンジンを実行できますcodeclimate analyze -e duplication
Reekは6つの出力形式をサポートしています。
--format html )--format yaml 、yamlレポートも参照)--format json )--format xml )--format github ) Reekの「Rails」を作成することは、ディレクトリ固有の構成(Reek Talkのdirectory directives )をサポートするため、かなり簡単です。これを構成ファイルに追加するだけです。
directories :
" app/controllers " :
IrresponsibleModule :
enabled : false
NestedIterators :
max_allowed_nesting : 2
UnusedPrivateMethod :
enabled : false
InstanceVariableAssumption :
enabled : false
" app/helpers " :
IrresponsibleModule :
enabled : false
UtilityFunction :
enabled : false
" app/mailers " :
InstanceVariableAssumption :
enabled : false
" app/models " :
InstanceVariableAssumption :
enabled : falseただし、Reekは構成エントリをマージしないため、既に「アプリ/コントローラー」または「アプリ/ヘルパー」のディレクトリディレクティブがある場合は、上記のYAMLサンプルを構成ファイルにコピーする代わりに、それらのディレクティブを更新する必要があります。
あなたが検討するかもしれない他の静的コードアナライザーの網羅的ではないリスト:
Reek Coreチームは次のとおりです。
リークの元の著者はケビン・ラザフォードです。
Reekのロゴの著者はSonja Heinenです。
注目すべき貢献は次のとおりです。