🛠

Rubyで抽象メソッド実装を強制するならNoMethodError

に公開

この記事は Codex を利用して執筆しているため、記述に矛盾が含まれる可能性があります。お気づきの点があればぜひ教えてください。

Rubyで継承先に実装を強制したい時は、抽象メソッドっぽく「ここで定義してね」と明示する仕組みが欲しくなるナリよね。そんな時にNotImplementedErrorを使いたくなるけれど、Rubyの標準的な流儀ではNoMethodErrorを投げる方が自然ナリ。

NoMethodErrorを使う理由ナリ

  • NoMethodErrorは「そのメソッドが呼び出せなかった」ことを表す例外で、Rubyのmethod_missingが返すデフォルトのエラーと同じ振る舞いナリ。
  • 呼び出し側は「メソッドが存在しない」という明確なシグナルを受け取れるため、実装忘れを気づきやすいナリ。
  • NotImplementedErrorは「この環境では未サポート」という意味合いで使われることが多く、実装漏れの検知用途には適さないナリ。

実装例ナリ

継承元で抽象メソッドを定義し、実装を強制する場合は次のように書くナリ。

def perform
  fail NoMethodError, "undefined method #{self.class}##{__method__}"
end
  • self.class__method__を組み合わせて「どのクラスのどのメソッドが未定義か」をメッセージに埋め込めるナリ。
  • failキーワードはraiseのエイリアス。こんな風に使うと、呼び出し側でも通常の未定義メソッドエラーとして扱えるナリ。

NotImplementedErrorを避ける理由ナリ

  • Ruby本体では、OSやビルドによって提供できない機能を知らせるためにNotImplementedErrorを投げるケースがあるナリ(例: 特定プラットフォームで未対応のシステムコール)。
  • 実装漏れでこの例外を投げると、利用者が「環境差異かもしれない」と誤解する恐れがあるナリ。
  • 似た名前だけど用途が違うので、抽象メソッドの強制には向かないナリ。

まとめナリ

  • 継承先に実装を求めるならNoMethodErrorを投げて、Rubyが想定する「メソッドが無い」流れに乗るナリ。
  • NotImplementedErrorは環境未対応の通知向け。似ているけれど用途が違うので注意ナリ。
  • メッセージにクラス名とメソッド名を含めておくと、どこを実装すべきか一目瞭然ナリ。
GitHubで編集を提案

Discussion