スキップしてメイン コンテンツに移動

Rubyリフレクション入門

Rubyリフレクション入門

Ruby実践とリフレクション

Rubyはオブジェクト指向言語として、リフレクション機能が豊富です。リフレクションを使うと、クラスやオブジェクトの内部構造を動的に調べたり、メソッドを動的に呼び出したりできます。実際に開発で頻繁に使われるのは、Object#methodsModule#instance_methodsなどで、クラスが持つメソッド一覧を取得するケースです。

method_defined? と respond_to? の使い分け

メソッドが定義されているかを確認する際に、Module#method_defined?Object#respond_to?は似たような役割を持ちますが、微妙に使い分けが必要です。method_defined?はクラスやモジュールに直接定義されたメソッドを調べ、継承チェーンは考慮しません。一方、respond_to?はオブジェクトが実際に呼び出せるかどうかを判定し、プロキシやメソッド_missingを通じて動的に生成されるメソッドも含めます。

methods と instance_variables で動的確認

オブジェクトの状態を動的に把握したい場合、Object#methodsで公開メソッド一覧を取得し、Object#instance_variablesで保持しているインスタンス変数を確認します。これらを組み合わせることで、例えば「あるオブジェクトが特定のプロパティを持っているか」や「特定の振る舞いを実装しているか」を動的にチェックできます。動的確認はテストコードやDSL構築時に非常に有用です。

メタプログラミング入口としての実践例

リフレクションを活用したメタプログラミングの入口として、以下のようなパターンがあります。

class DynamicBuilder
  def self.build(method_name, &block)
    define_method(method_name, &block)
  end
end

DynamicBuilder.build(:greet) { puts "Hello, world!" }
DynamicBuilder.new.greet

上記ではdefine_methodを使い、実行時にメソッドを追加しています。method_defined?で既に存在するか確認し、respond_to?で呼び出し可能かをチェックすることで、より安全にメタプログラミングを行えます。こうしたテクニックは、APIクライアントやORMのように動的にフィールドを生成するライブラリで頻繁に利用されます。

この記事はAIによって作成されました。

コメント