Listing an Objects Methods
Listing an Object s Methods
Problem
Given an unfamiliar object, you want to see what methods are available to call.
Solution
All Ruby objects implement the Object#methods method. It returns an array containing the names of the object's public instance methods:
Object.methods # => ["name", "private_class_method", "object_id", "new", # "singleton_methods", "method_defined?", "equal?", … ]
To get a list of the singleton methods of some object (usually, but not always, a class), use Object#singleton_methods:
Object.singleton_methods # => [] Fixnum.singleton_methods # => ["induced_from"] class MyClass def MyClass.my_singleton_method end def my_instance_method end end MyClass.singleton_methods # => ["my_singleton_method"]
To list the instance methods of a class, call instance_methods on the object. This lets you list the instance methods of a class without instantiating the class:
''.methods == String.instance_methods # => true
The output of these methods are most useful when sorted:
Object.methods.sort # => ["<", "<=", "<=>", "==", "===", "=~", ">", ">=", # "__id__", "__send__", "allocate", "ancestors", … ]
Ruby also defines some elementary predicates along the same lines. To see whether a class defines a certain instance method, call method_defined? on the class or respond_to? on an instance of the class. To see whether a class defines a certain class method, call respond_to? on the class:
MyClass.method_defined? :my_instance_method # => true MyClass.new.respond_to? :my_instance_method # => true MyClass.respond_to? :my_instance_method # => false MyClass.respond_to? :my_singleton_method # => true
Discussion
It often happens that while you're in an interactive Ruby session, you need to look up which methods an object supports, or what a particular method is called. Looking directly at the object is faster than looking its class up in a book. If you're using a library like Rails or Facets, or your code has been adding methods to the built-in classes, it's also more reliable.
Noninteractive code can also benefit from knowing whether a given object implements a certain method. You can use this to enforce an interface, allowing any object to be passed into a method so long as the argument implements certain methods (see Recipe 10.16).
If you find yourself using respond_to? a lot in an interactive Ruby session, you're a good customer for irb's autocomplete feature. Put the following line in your .irbrc file or equivalent:
require 'irb/completion' #Depending on your system, you may also have to add the following line: IRB.conf[:use_readline] = true
Then you can type (for instance) "[1,2,3].", hit the Tab key, and see a list of all the methods you can call on the array [1, 2, 3].
methods, instance_methods, and singleton_methods will only return public methods, and method_defined? will only return true if you give it the name of a public method. Ruby provides analagous methods for discovering protected and private methods, though these are less useful. All the relevant methods are presented in Table 10-1.
Goal |
Public |
Protected |
Private |
---|---|---|---|
List the methods of an object |
methods or public_methods |
protected_methods |
private_methods |
List the instance methods defined by a class |
instance_methods or public_instance_methods |
protected_instance_methods |
private_instance_methods |
List the singleton methods defined by a class |
singleton_methods |
N/A |
N/A |
Does this class define such-and-such an instance method? |
method_defined? or public_method_defined? |
protected_method_defined? |
private_method_defined? |
Will this object respond to such-and-such an instance method? |
respond_to? |
N/A |
N/A |
Just because you can see the names of protected or private methods in a list doesn't mean you can call the methods, or that respond_to? will find them:
String.private_instance_methods.sort # => ["Array", "Float", "Integer", "String", "'", "abort", "at_exit", # "autoload","autoload?", "binding", "block_given?", "callcc", … ] String.new.respond_to? :autoload? # => false String.new.autoload? # NoMethodError: private method 'autoload?' called for "":String
See Also
- To strip away irrelevant methods, see Recipe 10.3, " Listing Methods Unique to an Object"
- Recipe 10.4, "Getting a Reference to a Method," shows how to assign a Method object to a variable, given its name; among other things, this lets you find out how many arguments a method takes
- See Recipe 10.6, "Listening for Changes to a Class," to set up a hook to be called whenever a new method or singleton method is defined for a class
- Recipe 10.16, "Enforcing Software Contracts"