- 更新日: 2014年2月8日
- Ruby
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 独自のクラス、メソッドも含まれてます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Myarr < Array def self.foo puts "foo" end def bar puts "bar" end def baz puts "baz" end end |
ここから pry。頭の行数は削除してます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ bundle exec rails c pry(main)> class Myarr < Array pry(main)* def self.foo pry(main)* puts "foo" pry(main)* end pry(main)* pry(main)* def bar pry(main)* puts "bar" pry(main)* end pry(main)* pry(main)* def baz pry(main)* puts "baz" pry(main)* end pry(main)* end => nil pry(main)> => nil pry(main)> myarr = Myarr.new => [] pry(main)> arr = Array.new => [] |
各インスタンスのメソッド、メソッド数を確認
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
pry(main)> myarr.methods => [:bar, :baz, :inspect, :to_s, :to_a, :to_ary, ... pry(main)> myarr.methods(false) => [] pry(main)> myarr.methods.size => 253 pry(main)> arr.methods.size => 251 |
Object#methods の引数が偽(false)の時は Object#singleton_methods(false) と同じになるそうです。myarr には特異メソッドを何も定義してないので、myarr.methods(false) は空の配列を返します。
myarr に対して呼び出せる Myarr で定義されたメソッドのみを取得
配列の引き算(減算)を用いて取得。
1 2 3 4 5 6 7 8 |
pry(main)> myarr.methods - arr.methods => [:bar, :baz] pry(main)> myarr.methods - myarr.class.superclass.new.methods => [:bar, :baz] pry(main)> myarr.methods - myarr.class.superclass.instance_methods => [:bar, :baz] |
myarr.methods で取得できるのは、あくまでも myarr に対して呼び出せるメソッドのみ。なので、myarr のクラスである Myarr クラスのクラスメソッド(Myarr.foo)は取得されません。myarr(Myarrクラスのインスタンス)に対して foo は呼び出せないため。
続いて、Module#instance_methods を用いて取得。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
pry(main)> myarr.class.instance_methods => [:bar, :baz, :inspect, :to_s, :to_a, ... pry(main)> myarr.class.instance_methods(false) => [:bar, :baz] pry(main)> myarr.class.instance_methods.size => 253 |
Module#instance_methods を使うと、定義したクラスのインスタンスメソッドを取得できます。引数で false を渡すと、親クラスのインスタンスメソッドを除きます。myarr.class はすなわち Myarr クラスのことなので以上の結果となる。
Myarr のクラスメソッドを取得
Classクラスのインスタンス(ここでは Myarr クラス)に対して、methods を呼び出す方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
pry(main)> myarr.class.methods => [:foo, :[], :try_convert, :wrap, :yaml_tag, :allocate, :new, :superclass, ... pry(main)> myarr.class.methods(false) => [:foo] |
また、クラスメソッドとはクラス(Classクラスのインスタンス: Myarr クラス)の特異メソッドであるので、Myarr クラスに対する singleton_methods で取得できる。
1 2 3 4 5 6 |
pry(main)> myarr.class.singleton_methods => [:foo, :[], :try_convert, :wrap, :yaml_tag] pry(main)> myarr.class.singleton_methods(false) => [:foo] |
myarr.class.methods では、継承ツリーの途中のクラスで定義されている、Myarr クラスが反応できるメソッドが含まれるのに対し、myarr.class.singleton_methods では、親クラスと子クラスの特異メソッドのみが含まれています。
1 2 3 4 |
pry(main)> arr.class.singleton_methods => [:[], :try_convert, :wrap, :yaml_tag] |
:[], :try_convert, :wrap, :yaml_tag らのメソッドは、Array クラスの特異メソッドだろうと予測したらその通りでした。
myarr に特異メソッドを定義
1 2 3 4 5 6 7 8 9 |
pry(main)> def myarr.hoge pry(main)* puts "hoge" pry(main)* end pry(main)> myarr.methods(false) => [:hoge] pry(main)> myarr.singleton_methods(false) => [:hoge] |
Object#methods(false) か Object#singleton_methods(false) で、インスタンスの特異メソッドを取得できます。
ということで、以下のように理解しました。
Object#methods
methods のレシーバであるオブジェクト(Class クラスのインスタンスも含む)に対して呼び出せるメソッド一覧を取得。
Module#instance_methods
instance_methods のレシーバであるクラス・モジュールに定義されているインスタンスメソッド一覧を取得。
Object#singleton_methods
singleton_methods のレシーバであるオブジェクト(Class クラスのインスタンスも含む)に定義されている特異メソッド一覧を取得。
- – 参考リンク –
- instance method Object#methods
- instance method Module#instance_methods
- instance method Object#singleton_methods
- RubyMotion – Ruby(Motion)でmethodsを使ってメソッド検索 – Qiita
- Rubyを知ろう
- Ruby の関連記事
- Gemの作り方(Ruby Gem)
- ローカル開発中のgemをGemfileに書いてインストール
- 熊本地震の余震が夜に多いのは本当か?Rubyプログラムで検証してみた
- El Capitanでgemのnative extensionビルド失敗に対応
- Rubyで親クラスから子クラスの定数を参照
- MacabをRubyで使う
- rbenv/ruby-buildでRuby最新バージョンをインストール
- Rubyでクラスインスタンス変数にインスタンスメソッドからアクセス
- 距離1kmあたりの緯度・経度の度数を計算(日本・北緯35度)
- Google Maps Geocoding APIで住所から緯度・経度を取得するRubyコード
Leave Your Message!