🛠
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は環境未対応の通知向け。似ているけれど用途が違うので注意ナリ。 - メッセージにクラス名とメソッド名を含めておくと、どこを実装すべきか一目瞭然ナリ。
Discussion