Rubyリフレクション入門
Ruby実践とリフレクション
Rubyはオブジェクト指向言語として、リフレクション機能が豊富です。リフレクションを使うと、クラスやオブジェクトの内部構造を動的に調べたり、メソッドを動的に呼び出したりできます。実際に開発で頻繁に使われるのは、Object#methodsやModule#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のように動的にフィールドを生成するライブラリで頻繁に利用されます。
コメント
コメントを投稿