RubyCriticでRubyコードの品質を向上させる:視覚的な分析と継続的な改善
RubyCriticは、Rubyアプリケーションにおけるコードの臭い(code smells)、コード構造、テストのしやすさ、テストカバレッジなどを可視化したレポートを提供するツールです。
現在も活発に開発が続けられており、新しいコード解析機能が次々と追加されています。リリース情報を定期的にチェックする価値は十分にあります。
本記事では、RubyCriticのメリット、内部の依存関係、そしてレポートの読み方について解説します。
それでは始めましょう!
Ruby on RailsアプリケーションにRubyCriticを選ぶ理由
プロジェクトのコード改善点を一箇所で確認したいのであれば、RubyCriticの導入を検討すべきです。開発プロセスにRubyCriticを組み込むことで、開発チームが技術的負債(テクニカルデット)の解消に費やす時間を確実に削減できます。ほとんどの技術的負債は開発段階で洗い出せるようになります。
RubyCriticがプロジェクトや開発プロセスにもたらす主なメリットは以下の通りです:
- 情報を一箇所に集約できる
- 視覚的なレポート
- 簡単なインストール
- 設定不要(ゼロコンフィグ)
- カスタマイズ可能
- 拡張性 — 独自のオープンソース連携も作成できる
- バッジ生成機能 🎉
RubyCriticの仕組みを理解するために、レポート生成に使われている内部依存関係を見ていきましょう。
RubyCriticの内部依存関係
プロジェクトにRubyCriticを追加すると、いくつかの依存gemも一緒にインストールされます。
中でも重要なのが、Reek、Flay、Flogという3つのgemです。これらの依存関係によって、RubyCriticはコードに関する貴重な情報を表示できます。それぞれの仕組みを理解しておくと、RubyCriticをより効果的に活用できるでしょう。
Reek:Rubyのコード臭を検出する
Reekは、Rubyのコード臭を検出するためのgemです。コードの「悪臭」とは、誤ったコードを特定することではなく、そのコードをもっと良い形で書けるかどうかを分析することを指します。
Reekの分析は、何かを別の方法で実装できるかどうかを識別します。どうやって修正すべきかまでは提案しません。多くのコード臭はビジネスロジックや開発者の言語経験に関わるものだからです。
例えば、if文はメタプログラミングの手法を使って書き換えることもできます。しかし、どう修正すべきかはプロジェクトの文脈に応じて開発者が判断することです。この場合、最適な解決策を示せるライブラリは存在しません。
Reekは非常に幅広い種類のコード臭を検出します。以下のような対象を調査・識別します:
- クラス
- 属性
- メソッド
- パラメータ
- モジュール
- イテレータ
- ポリモーフィズムの実装
コード臭を発見することで、コードの可読性と保守性を高めるための具体的なアクションにつなげられます。
Reekでは以下のようなカスタム設定も可能です:
- タイプごとに検出器を無効化する
- スキャン対象からディレクトリを除外する
- フィルターを使って警告を抑制する
さらに、特定のコードをスキャン対象から除外することもできます。これは、まだ完成していないコードやリファクタリング前のコード、あるいはレガシーコードを扱う際に非常に便利な機能です。
Reekの動作例を見てみましょう。次のコードでは、例外が単にeと定義されています。
eが例外を意味することは容易に想像できますが、他の例外が存在する場合はどうでしょうか?例外を正しく識別することが、良いコードを維持するための最善の方法です。
ReekはeをUncommunicativeVariableName(分かりにくい変数名)として検出し、警告を表示します。
Flay:Rubyコードの重複をチェックする
Flayは、Rubyコードの構造的な類似性を特定します。主な機能は以下の通りです:
- プロジェクト内のコード重複の検出
- あらゆるコードレベルでの差異チェック
- コードの良さを測るスコアの生成(スコアが低いほど良いコード)
Flayがコードの類似性を報告したら、それはリファクタリングが必要なサインです。見逃さないでください!重複コードはバグへの入り口です。一箇所を修正しても別の場所を忘れると、さらなるバグが発生します。
Flay自身のソースコードに対して実行してみると、その動作を確認できます:
Flayはこの2つのコード間の類似性を検出しました:
注目すべきは、コードの表記は完全には同じではないものの、機能は同一であり、重複を避けるためにリファクタリングできるという点です。これこそがFlayの魔法です!
Flog:Rubyコードの複雑度を調べる
Flogは、コードがどれだけテストしにくいかをチェックします。コードの各行に複雑度スコアを設定し、メソッドやクラスごとに合計スコアを算出します。
スコアが高いほど、実装が高度に複雑であることを意味するため、リファクタリングが必要です。
Flogの実際の動作を見てみましょう!小さな変更でもスコアが変動します。
最初のコードでは、orによるチェックがあることで、スコアが0.4ポイント増加していることに注目してください。
その他のRubyCritic依存関係
RubyCriticは、以下のような他のランタイム依存関係も使用しています:
byebug— Rubyアプリケーションのデバッグを強化するツールです。プログラムを行ごとに実行したり、ブレークポイントを追加したり、実行時に値を評価・追跡したりできます。まだデバッグにputsを使っているなら、Byebugの機能とコマンドを知る絶好のタイミングです。rubocop— Rubyコードのリンターツールです。Rubyコミュニティで使われているスタイルガイドに従ったり、独自のコードスタイルを適用したりできます。チーム内で基準を統一し、スペースやタブに関する些細な衝突を避けるのに非常に役立ちます。SimpleCov— Rubyアプリケーションのコードカバレッジを確認するツールです。テストと併せて実行するよう設定でき、カバレッジの指標を提供してくれるため、どこに注意を払い、より良いテストケースを作成するために時間を投資すべきかを把握できます。
RubyCriticの依存関係リストをぜひ詳しく覗いてみてください。
Ruby on RailsアプリでのRubyCriticの使い方
RubyCriticには充実したドキュメントがあり、大きな設定なしですぐに始められます。そこで本記事では、レポートを分析するための機能の使い方に焦点を当てます。
RubyCriticは「Code」「Smells」「Coverage」の3種類のレポートを提供しています。順番に見ていきましょう。
RubyCriticのオーバービュー
「Overview」ページでは、ドーナツチャートでプロジェクト全体のスコアと評価(Aが最高、Fが最低)が表示されます。「Summary」セクションには、各評価の詳細として、ファイル数、チェーン数(コミットによる変更)、検出されたコード臭の数などが示されます。

「Churn vs Complexity」セクションでは、最も複雑度の高いクラスをすぐに特定でき、おそらくそこが最初に注目すべきポイントとなるでしょう。
このグラフをより深く理解するために、「コードチェーン(変更頻度)」についておさらいしておきましょう。頻繁に変更されるコードは、ロジックやビジネスドメインに何らかの問題があることを示唆している可能性があります。いずれにせよ、「Churn vs Complexity」を見ることで、プロジェクト全体の痛点(ペインポイント)を把握できます。
Codeレポート
「Code」レポートでは、クラスごとのスコアが表示され、チェーン数、複雑度、重複、コード臭の各指標も確認できます。
このリストは任意の列で並べ替えられるため、影響度の高い要素を確認し、最も重大な問題から優先的に対処できます。

さらに、このリストにはフィルター機能があり、クラス名で素早く検索することも可能です。
クラス名をクリックすると、クラスのコードと以下のような詳細な指標を含むページが開きます:
- コード行数
- メソッド数
- 算出されたチェーン数
- メソッドごとの複雑度
- 複雑度スコア(クラス合計)
- 検出された重複の数
- コード臭の数
問題が見つかったコード行はハイライト表示されます(Reek gemから提供される情報に基づきます)。
Flogが問題を検出した場合はスコアが表示され、Flayが重複コードを検出した場合もその旨が確認できます。

Smellsレポート
「Smells」ページでは、コード臭の種類、発生箇所の正確な位置、修正ステータスが表示されます。
前述の通り、コード臭はReekによって検出されており、このページでも並べ替えやフィルタリングが利用できます。
クラス名をクリックすると、コードの詳細ページが開きます。また、コード臭の種類ごとにクラスをグループ化して表示することもできます(「Code」ページではコード臭の数しか表示されないため、これは便利な違いです)。

Coverageレポート
最後に、「Coverage」レポートでは、クラスの評価と各クラスのカバレッジ率を確認できます。「Code」や「Smells」レポートのリストとは異なり、「Coverage」のリストは並べ替えやフィルタリングには対応していません。
確認できるのはコードカバレッジの割合のみで、追加情報はありません。

SimpleCovのレポートを統合すれば、このページの価値と実用性はさらに高まるでしょう。とはいえ、プロジェクトのテストカバレッジを手軽に確認したい場合には、「Coverage」レポートは十分に役立ちます。
まとめ
本記事では、まずRubyアプリケーションにおけるRubyCriticのメリットを簡単に紹介し、次に内部依存関係であるReek、Flay、Flogについて掘り下げました。その後、RubyCriticのレポートの読み方と分析方法を解説しました。
次のステップとしては、CIパイプラインにRubyCriticを組み込む方法を検討してみてください。
楽しいリファクタリングライフを!
P.S. Ruby Magicの記事を公開と同時にお読みになりたい方は、Ruby Magicニュースレターをご購読ください。記事を見逃すことはありません!
Brena Monteiro
ゲスト執筆者のBrenaは、新人開発者のメンタリングに情熱を注ぐテックリードであり、高いパフォーマンスを発揮するチームの開発と統括の経験を持っています。スケーラブルなAPIやクラウドサービス間の連携構築の経験があり、進化的アーキテクチャに強い関心を持ち、Extended Reality(XR)のアプレンティスでもあります。
Brena Monteiroのすべての記事を見る
-
AppSignalが振り返る2023年のRubyハイライト:最も読まれた記事トップ5
2023年も残りわずかとなりました。そこで今回は、AppSignalで今年最も読まれたRuby記事トップ5をご紹介します! 第5位:Railsのログを最大限に活用する方法 Railsでのロギングは、始めるのはとても簡単ですが、使いこなしてマスターするのはそう簡単ではありません。この記事では、アプリケーションのログから最大限の価値を引き出すための実践的なテクニックを解説しています。 第4位:Ruby on Railsアプリケーションにおけるビジネスロジックの整理術 全2回構成のシリーズ第1回目となるこの記事では、Railsアプリケーションでビジネスロジックを整理するための定番手法を幅広く取り上げ
-
Rails × Hotwire入門:JavaScriptを書かずにSPAのような高速Webアプリを作る方法
ページ遷移やフォーム送信を高速化したい、複雑なページをコンポーネント単位に分割したい——しかもJavaScriptのコードを一切書かずに。そんな願いを叶えてくれるのがHotwireです。本記事では、サーバーサイドレンダリングを実現するツール「Hotwire」を活用して、Railsアプリケーションを次のレベルへ引き上げる方法を、実例を交えながら詳しく解説します。 Hotwireとは? Hotwireは、JSONの代わりにHTMLを通信経路上でやり取りすることで、JavaScriptを書かずにモダンなWebアプリケーションを構築できるフレームワークです。HTMLベースの配信により、ページの表示