Ruby の Object#methods, Module#instance_methods, Object#singleton_methods でメソッドを取得

Rails やってて Ruby で親クラスを除いて、そのクラス自身で定義されたメソッドを取得したいことがあって調べました。基本、Object#methods, Module#instance_methods, Object#singleton_methods の3つで、methods, instance_methods には、各々アクセス制御の public_, protected_, private_ の接頭辞がついたメソッドがあります。

スポンサーリンク

— 環境 —
ruby 2.0.0
rails 4.0.1
pry 0.9.12.6

サンプルクラス定義とインスタンス作成

以下のクラスを定義しインスタンス作成して、pry で実行して試しました。rails 環境の pry で試しましたので、rails 独自のクラス、メソッドも含まれてます。

ここから pry。頭の行数は削除してます。

各インスタンスのメソッド、メソッド数を確認

Object#methods の引数が偽(false)の時は Object#singleton_methods(false) と同じになるそうです。myarr には特異メソッドを何も定義してないので、myarr.methods(false) は空の配列を返します。

myarr に対して呼び出せる Myarr で定義されたメソッドのみを取得

配列の引き算(減算)を用いて取得。

myarr.methods で取得できるのは、あくまでも myarr に対して呼び出せるメソッドのみ。なので、myarr のクラスである Myarr クラスのクラスメソッド(Myarr.foo)は取得されません。myarr(Myarrクラスのインスタンス)に対して foo は呼び出せないため。

続いて、Module#instance_methods を用いて取得。

Module#instance_methods を使うと、定義したクラスのインスタンスメソッドを取得できます。引数で false を渡すと、親クラスのインスタンスメソッドを除きます。myarr.class はすなわち Myarr クラスのことなので以上の結果となる。

Myarr のクラスメソッドを取得

Classクラスのインスタンス(ここでは Myarr クラス)に対して、methods を呼び出す方法。

また、クラスメソッドとはクラス(Classクラスのインスタンス: Myarr クラス)の特異メソッドであるので、Myarr クラスに対する singleton_methods で取得できる。

myarr.class.methods では、継承ツリーの途中のクラスで定義されている、Myarr クラスが反応できるメソッドが含まれるのに対し、myarr.class.singleton_methods では、親クラスと子クラスの特異メソッドのみが含まれています。

:[], :try_convert, :wrap, :yaml_tag らのメソッドは、Array クラスの特異メソッドだろうと予測したらその通りでした。

myarr に特異メソッドを定義

Object#methods(false) か Object#singleton_methods(false) で、インスタンスの特異メソッドを取得できます。

ということで、以下のように理解しました。

Object#methods

methods のレシーバであるオブジェクト(Class クラスのインスタンスも含む)に対して呼び出せるメソッド一覧を取得。

Module#instance_methods

instance_methods のレシーバであるクラス・モジュールに定義されているインスタンスメソッド一覧を取得。

Object#singleton_methods

singleton_methods のレシーバであるオブジェクト(Class クラスのインスタンスも含む)に定義されている特異メソッド一覧を取得。

スポンサーリンク
私は以下の本で Ruby を覚えました。メタプログラミングRubyは入門を超える内容で難しめです。
スポンサーリンク
 
Twitterを使っていますのでフォローお願いたします!ブログの更新情報もつぶやいてます^^
(英語学習用)

Leave Your Message!