Meta Methodology

Ruby clutters its objects a lot with methods for metaprogramming other methods:

Class.instance_methods.grep /method/
=> [:instance_methods, :public_instance_methods,
:protected_instance_methods, :private_instance_methods,
:method_defined?, :public_method_defined?,
:private_method_defined?, :protected_method_defined?,
:public_class_method, :private_class_method, :instance_method,
:public_instance_method, :methods, :singleton_methods,
:protected_methods, :private_methods, :public_methods,
:method, :public_method, :singleton_method,

Class.private_instance_methods.grep /method/
=> [:method_added, :method_removed, :method_undefined,
:remove_method, :undef_method, :alias_method, :define_method,
:instance_methods_for, :__method__, :singleton_method_added,
:singleton_method_removed, :singleton_method_undefined,

It's so many methods, because working with methods is a multi-dimensional problem:

Let's put everything in some order:

Method Lists

Methods returning method lists always take a boolean argument, which will prevent inheritance if set to false

Method From Target Visibility
Object#singleton_methods instance singleton public + protected
Object#methods instance instance + singleton public + protected
Object#public_methods instance instance + singleton public
Object#protected_methods instance instance + singleton protected
Object#private_methods instance instance + singleton private
Module#instance_methods class instance public + protected
Module#public_instance_methods class instance public
Module#proected_instance_methods class instance proected
Module#private_instance_methods class instance private

Method Defined? Checks

Instead of listing all methods and checking if the resulting array contains a specific method, you can also directly check if a method is defined.

Since Ruby 2.6, you can also pass in a boolean as second argument which will ignore the inheritance chain (similar like it is with the method listings above).

Method From Target Visibility
Module#method_defined? class instance all
Module#public_method_defined? class instance public
Module#protected_method_defined? class instance protected
Module#private_method_defined? class instance private

Method Getters

These methods will return method objects for further metaprogramming action:

Method From Target Visibility Returns
Object#singleton_method instance singleton all Method
Object#method instance instance + singleton all Method
Object#public_method instance instance + singleton public Method
Module#instance_method class instance all UnboundMethod
Module#public_instance_method class instance public UnboundMethod

Method Manipulation

These methods will actually modify your objects:

Method From Target Visibility
Object#define_singleton_method instance singleton public
Module#define_method (private) class instance public (see notes)
Module#remove_method (private) class instance -
Module#undef_method (private) class instance -
Module#alias_method (private) class instance same

Method Hooks

Hook methods can be defined and will be called by the Ruby interpreter when the respective event happens:

Method From Target
BasicObject#singleton_method_added instance singleton
BasicObject#singleton_method_undefined instance singleton
BasicObject#singleton_method_removed instance singleton
Module#method_added class instance
Module#method_undefined class instance
Module#method_removed class instance
BasicObject#method_missing class instance

Method Visibility Modifiers

Besides public, protected, and private, there are two additional methods with the sole purpose of changing a method's visibility:

Method From Target Description
Module#public_class_method class singleton Makes a class's singleton method public
Module#private_class_method class singleton Makes a class's singleton method private

Current Method Name

There are two underscore-wrapped methods that return the current method's name:

Method From Returns
Kernel#__method__ (private) anywhere Original method name
Kernel#__callee__ (private) anywhere Aliased method name

A Better API for Metaprogramming Methods?

Metaprogramming in Ruby has evolved over time, but it might be a good idea to clean it up a little - A good example of how to clean up one of Ruby's other metaprogramming APIs is the instance gem. It gives you a neat API for working with an object's state, like setting instance variables. Someone feels like building a similar gem for Ruby's Method APIs?

More Idiosyncratic Ruby