クラスのインスタンスメソッドのリストを取得する


98

私はクラスを持っています:

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

どのように私は(このクラスでは、私のメソッドのリストを取得することができmethod1method2method3)?

回答:


114

それ自体ができることにTestClass.instance_methods興味がない限り、あなたは実際にを望みTestClassます。

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

TestClass.methods.grep(/method1/) # => []
TestClass.instance_methods.grep(/method1/) # => ["method1"]
TestClass.methods.grep(/new/) # => ["new"]

または、オブジェクトに対してmethods(ではなくinstance_methods)を呼び出すことができます。

test_object = TestClass.new
test_object.methods.grep(/method1/) # => ["method1"]

3
へえ、あなたは私を47秒でそれに打ち負かした。+1
Phrogz

2
試してみるとprint TestClass.new.instance_methods、このエラーが発生しますmy_class.rb:10:in <main>: undefined method instance_methods for #<TestClass:0x96b9d20> (NoMethodError)
Vladimir Tsukanov

あなただけを行う必要がありますTestClass.new.methods。多分「それ」は私の答えがあいまいだった。
Andrew Grimm

Ruby 1.9以降では、メソッド名の配列は文字列ではなくシンボルであることに注意してください。
Phrogz

1
@Phrogz:はい。ただし、正規表現を使用できます。クトゥルフを召喚することすらありません!:)あなたは[:method1]代わりに得るでしょう。
Andrew Grimm

113
TestClass.methods(false) 

そのクラスにのみ属するメソッドのみを取得します。

TestClass.instance_methods(false) 指定された例からメソッドを返します(それらはTestClassのインスタンスメソッドであるため)。


2
これは、クラスが疑似インターフェイス/抽象基本クラスからのポリモーフィングされたメソッドを持っているかどうかをテストするための優れた方法であり、メソッドを直接呼び出す必要はありません。
Daniel Doezema 2013

2
受け入れられた答えは素晴らしいですが、これはより多くの人々がここに来るのでしょう!
アーロン

これは間違いなく受け入れられる答えになるはずです。ありがとう!
Vinicius Brasil

38
TestClass.instance_methods

またはすべての継承されたメソッドなし

TestClass.instance_methods - Object.methods

(「TestClass.methods-Object.methods」でした)


25
または継承されたメソッドなし:TestClass.methods(false)
佐和

2
@sawa TestClass.methods(false)は空を返します
ウラジミールツカノフ

1
この答えは間違っています。結果は含まないmethod1method2またはmethod3それらはの方法であるように、インスタンスのクラスののではないメソッドTestClassオブジェクト自体。
Phrogz

1
@Phrogz:おっと...はい、「TestClass.instance_methods-Object.methods」、または「TestClass.new.methods-Object.methods」...コンソールを起動しないことを教えてくれます。この回答を削除するか、編集するのが最善ですか?
13:13

1
@Pavling正解になるように間違いなく回答を編集してください。(すぐに、OPがクレジットを他の誰かに割り当てる前に!:)
Phrogz

6

デバッグlookseeなどのgemを使用して、より詳細なリスト(たとえば、クラスを定義することで構造化)を取得できます。


6
$ irb --simple-prompt

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

tc_list = TestClass.instance_methods(false)
#[:method1, :method2, :method3]
puts tc_list
#method1
#method2
#method3

2
これは他の回答と非常に似ており、追加の情報や明確さを追加しません。
2014

3
あなたもそれが非常に遅いと言及するのに失敗しました。:D
ダグラスG.アレン14

2

Ruby Docのinstance_methodsによると

レシーバーのパブリックおよび保護されたインスタンスメソッドの名前を含む配列を返します。モジュールの場合、これらはpublicおよびprotectedメソッドです。クラスの場合、これらはインスタンス(シングルトンではない)メソッドです。オプションのパラメーターがfalseの場合、祖先のメソッドは含まれません。公式ドキュメントの例を取り上げます。

module A
  def method1()  
    puts "method1 say hi"
  end
end
class B
  include A #mixin
  def method2()  
     puts "method2 say hi"
  end
end
class C < B #inheritance
  def method3() 
     puts "method3 say hi"
  end
end

出力を見てみましょう。

A.instance_methods(false)
  => [:method1]

A.instance_methods
  => [:method1]
B.instance_methods
 => [:method2, :method1, :nil?, :===, ...# ] # methods inherited from parent class, most important :method1 is also visible because we mix module A in class B

B.instance_methods(false)
  => [:method2]
C.instance_methods
  => [:method3, :method2, :method1, :nil?, :===, ...#] # same as above
C.instance_methods(false)
 => [:method3]

0

独自のメソッドのみを取得し、継承されたメソッドを除外するには:

インスタンス内から:

self.methods - self.class.superclass.instance_methods

外から:

TestClass.instance_methods - TestClass.superclass.instance_methods

クラスに追加します。

class TestClass
  class << self
    def own_methods
      self.instance_methods - self.superclass.instance_methods
    end
  end
end

TestClass.own_methods
=> [:method1, :method2, method3]

(Ruby 2.6.xを使用)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.