2

In Ruby we have simple ways to get all the local variables, global variables with local_variables and global_variables method.

We can list the constants with Object.constants

But is there a builtin way to list all the Object methods?

Something like this:

def foo() end
def bar() end
def baz() end

# As `Array.new.methods' or `Array.instance_methods` returns all the methods of an Array object...

# Code to return all the methods defined above    # => [:foo, :bar, :baz]

In IRB, I can write:

def foo() end
p [self.methods.include?(:foo), self.respond_to?(:foo)]

And the output is [true, true] in IRB, but in a file, the output to standard output is [false, false]

Similarly if I run the following code:

def foo() end
puts Object.new.methods.include?(:foo)

In IRB, I get true, and if it's saved in a file, I get false

Here's a link which didn't help much:

How to list all methods for an object in Ruby?

Just because it talks about getting methods of a class or a module. But I want to list the methods defined in the top self object.

15 Volts
  • 1,946
  • 15
  • 37
  • Because that talks about a User class, and I want to get all the instance method of the object, just like the above example... – 15 Volts Jun 12 '19 at 19:59
  • `SomeClass = Class.new { def foo; end; }` then `SomeClass.new.methods - Object.new.methods # => [:foo]` – Surya Jun 12 '19 at 20:06
  • @Surya, thanks for the valuable comment, but it actually creates a class. I don't want that. I want to list all the methods defined in top self object! You can simply list methods of a class with: `SomeClass = Class.new { def foo() end }.tap { |c| p c.instance_methods(false) }`, you get `[:foo] # => SomeClass` – 15 Volts Jun 12 '19 at 20:14

2 Answers2

3

The closest I could find is to call private_methods on the main object, with false as argument

Returns the list of private methods accessible to obj. If the all parameter is set to false, only those methods in the receiver will be listed.

def foo
  "foo"
end

def bar
  "bar"
end

def baz
  "baz"
end

p private_methods(false)
# [:include, :using, :public, :private, :define_method, :DelegateClass, :foo, :bar, :baz]

If you omit the argument, you also get all the private methods defined in Kernel or BasicObject.

In order to refine the list further, you could select the methods defined for Object:

p private_methods(false).select{|m| method(m).owner == Object}
#=> [:DelegateClass, :foo, :bar, :baz]

Only :DelegateClass is left, because it is defined in the top-level scope, just like :foo, :bar and :baz.

Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • Thank you very much, it works if you delete [:using, :define_method, :private, :public, :include, :DelegateClass] from the array! `private_methods(false) - [:using, :define_method, :private, :public, :include, :DelegateClass]` ... But may the RUBY_VERSION matter? I think I shouldn't hard code it like this!! – 15 Volts Jun 12 '19 at 20:34
  • 1
    @S.Goswami: Or `private_methods(false).select{|m| method(m).owner == Object}`. See edit. – Eric Duminil Jun 12 '19 at 20:44
1

You're getting false because methods defined in the top level context are private by default.

def foo; end

p self.private_methods.include?(:foo)
# => true

I'm not sure if this is documented anywhere.

In order to get all methods, including private ones, you'll need to do e.g.:

all_methods = self.methods | self.private_methods

Try it on repl.it: https://repl.it/@jrunning/DutifulPolishedCell

Jordan Running
  • 102,619
  • 17
  • 182
  • 182