108

I have a class:

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

How can I get a list of my methods in this class (method1, method2, method3)?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Vladimir Tsukanov
  • 4,269
  • 8
  • 28
  • 34

8 Answers8

129
TestClass.methods(false) 

to get only methods that belong to that class only.

TestClass.instance_methods(false) would return the methods from your given example (since they are instance methods of TestClass).

Bijan
  • 6,675
  • 6
  • 33
  • 29
  • 2
    This is great way to test if a class has polymorphed methods from a pseudo-Interface/Abstract base class without having to try and call the methods directly. – Daniel Doezema Apr 19 '13 at 13:03
  • 2
    Accepted answer is great but this one is likely what more people will come here for! – Aaron Apr 12 '16 at 14:36
  • This definitely should be the accepted answer. THANKS! – vinibrsl Jan 07 '19 at 11:23
  • @Aaron: I highly doubt that, since this answer is *wrong*. `Object#methods` returns the methods that you can *call* on an *object*. What are the methods you can call on an object? The ones that are defined in its *class*. Which means that `TestClass.methods` returns the list of methods you can *call* on `TestClass`, which are the methods that are defined in its class. What is `TestClass`'s class? It is `Class`. So, `TestClass.methods` gives you the methods that are defined in `Class`, not the ones that are defined in `TestClass`. Not sure how this answer got 116 upvotes, when anybody with even – Jörg W Mittag Sep 23 '20 at 12:40
  • … the most remote passing knowledge would instantly recognize it as wrong. Or, you know, just copy&pasting this code and running it would reveal that it is wrong. – Jörg W Mittag Sep 23 '20 at 12:41
  • @ViniciusBrasil: This answer is wrong, so it should *definitely not* be the accepted answer, and the fact that it has 116 upvotes is seriously sad, considering that it takes 1 second to just copy&paste the code and try it out, and less than one second to just think it through. – Jörg W Mittag Sep 23 '20 at 12:42
  • I can't recall what was going on 4+ years ago so I'll offer my best guess. The currently accepted answer is thorough and provides a great understanding of the differences between `Object#methods` and `Object#instance_methods`. I imagine that I found this answer's usage of the `false` argument to be what I was interested in as `TestClass.instance_methods.size` is 64 on Ruby 2.7.1 but `TestClass.instance_methods(false).size` is limited to the three defined. I probably was lazy and didn't want to chain `grep` ‍♂️ – Aaron Sep 24 '20 at 13:24
126

You actually want TestClass.instance_methods, unless you're interested in what TestClass itself can do.

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"]

Or you can call methods (not instance_methods) on the object:

test_object = TestClass.new
test_object.methods.grep(/method1/) # => ["method1"]
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
42
TestClass.instance_methods

or without all the inherited methods

TestClass.instance_methods - Object.methods

(Was 'TestClass.methods - Object.methods')

Pavling
  • 3,933
  • 1
  • 22
  • 25
  • 27
    or without inherited methods: `TestClass.methods(false)`. – sawa Jun 24 '11 at 13:23
  • 2
    @sawa `TestClass.methods(false)` returns empty – Vladimir Tsukanov Jun 24 '11 at 13:55
  • 1
    This answer is wrong; the results will not include `method1`, `method2`, or `method3`, as those are methods of _instances_ of the class, not methods of the `TestClass` object itself. – Phrogz Jun 24 '11 at 14:02
  • 1
    @Phrogz: Oops... yes, 'TestClass.instance_methods - Object.methods', or 'TestClass.new.methods - Object.methods'... that'll teach me for not firing up a console. Is it best for me to delete this answer, or edit it? – Pavling Jun 24 '11 at 14:13
  • @Phrogz - this answer works for me, i get _[:method1, :method2, :method3]_ with `print TestClass.new.methods - Object.methods` – Vladimir Tsukanov Jun 24 '11 at 14:13
  • @Vladimir @Phrogz The question was contradictory. In the title (before the edit by Theo), it was asking for class methods, and in the body, it's asking for `method1`, etc. – sawa Jun 24 '11 at 14:13
  • 1
    @Pavling Definitely edit your answer to be correct. (Quickly, before the OP assigns the credit to someone else! :) – Phrogz Jun 24 '11 at 14:16
  • @Phrogz: Keeping the (corrected) answer is also a good way of showing a potential "gotcha". – Andrew Grimm Jun 24 '11 at 14:25
7
$ 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
Douglas G. Allen
  • 2,203
  • 21
  • 20
5

According to Ruby Doc instance_methods

Returns an array containing the names of the public and protected instance methods in the receiver. For a module, these are the public and protected methods; for a class, they are the instance (not singleton) methods. If the optional parameter is false, the methods of any ancestors are not included. I am taking the official documentation example.

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

Let's see the output.

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]
Mukesh Kumar Gupta
  • 1,567
  • 20
  • 15
5

You can get a more detailed list (e.g. structured by defining class) with gems like debugging or looksee.

J-_-L
  • 9,079
  • 2
  • 40
  • 37
2

To get only own methods, and exclude inherited ones:

From within the instance:

self.methods - self.class.superclass.instance_methods

From outside:

TestClass.instance_methods - TestClass.superclass.instance_methods

Add it to the class:

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

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

(with ruby 2.6.x)

nakwa
  • 1,157
  • 1
  • 13
  • 25
0

If you have an instance but don't know the class name:

object.class.instance_methods(false)
# => Array of class instance methods