
You often hear that a method belongs to an object — but in Ruby, things are a bit more interesting.
Typically, methods are defined in classes and modules, and when you call one, Ruby searches for it along the ancestor chain. An individual object can also have its own methods — singleton methods, defined in its singleton class (eigenclass).
Where are methods located?
Let's look at a simple example:
ruby
class Post
def title
"Hello Ruby"
end
def self.recent
[]
end
end
post = Post.new
def post.preview
"Preview"
end
Here we have three different methods:
title— a regular instance method, defined in Post.recent— a class method, defined in the singleton class of the Post object.preview— a singleton method of the specific post instance.
The illustration shows exactly where these methods live. Note that Post is simultaneously a class for its instances and a regular object — an instance of Class.
That's precisely why Post itself also has a singleton class, in which its class methods are defined.

How does Ruby look up methods?
Now let's make the example more complex:
ruby
module Logging
def title = "Logging"
end
module Formatting
def title = "Formatting"
end
class BasePost
def title = "BasePost"
def self.recent = []
end
class Post < BasePost
prepend Logging
include Formatting
def title = "Post"
end
post = Post.new
def post.preview = "Preview"
When we call post.title, Ruby searches for the method in a specific order.
The lookup chain:

Ruby goes from top to bottom and stops at the first matching method.
Therefore:
ruby
post.title
# => "Logging"
post.preview
# => "Preview"
Even though title is defined in several places, the implementation from Logging wins because the module is included via prepend.
And preview is found directly in the singleton class of the post object.
You can check the chain yourself:
ruby
post.singleton_class.ancestors
# => [
# #<Class:#<Post:...>>,
# Logging,
# Post,
# Formatting,
# BasePost,
# Object,
# Kernel,
# BasicObject
# ]
An important nuance: prepend can also be used on a singleton class. In that case, modules included this way will be called before the class's own methods.
ruby
module Formatting
def preview
"Formatted Preview"
end
end
class Post
end
def post.preview = "Preview"
post.singleton_class.prepend Formatting
post.preview
What about class methods?
Let's return to the illustration: it shows that class methods are not a separate Ruby entity. They are ordinary singleton methods of the class object.
For example, BasePost.recent is defined on the BasePost object, which itself is an instance of Class.
At the same time, class methods are inherited:
ruby
Post.recent
# => []
Why? Because the lookup follows a different chain:

A child's singleton class inherits from the parent's singleton class. This is why class methods can also be inherited.
This is exactly the distinction the illustration shows: instance methods live in the regular class, while the class's own methods live in its eigenclass.
And if a method isn't found?
When no matching method is found, Ruby falls back to method_missing. Notably, method_missing itself is also found through the method lookup mechanism.
If we implement dynamic methods via method_missing, we should usually also override respond_to_missing? so that respond_to? correctly reflects the supported methods.
Part of metaprogramming in Ruby and Rails is built on these mechanisms.
Example: passing unhandled calls up the inheritance chain
ruby
class BasePost
def method_missing(name, *args, **kwargs, &block)
if name == :hello
"Hello from BasePost!"
else
super
end
end
def respond_to_missing?(name, include_private = false)
name == :hello || super
end
end
class Post < BasePost
def method_missing(name, *args, **kwargs, &block)
if name == :goodbye
"Goodbye from Post!"
else
super
end
end
def respond_to_missing?(name, include_private = false)
name == :goodbye || super
end
end
post = Post.new
post.goodbye # => "Goodbye from Post!"
post.hello # => "Hello from BasePost!"
post.unknown # => NoMethodError
post.respond_to?(:goodbye) # => true
post.respond_to?(:hello) # => true
post.respond_to?(:unknown) # => false
The order of processing for post.hello:
- Ruby doesn't find a regular
hellomethod and callsPost#method_missing. Postdoesn't handlehelloand callssuper.- Ruby moves on to
BasePost#method_missing. BasePosthandleshelloand returns the result.
For post.unknown, the same thing happens, but BasePost#method_missing also calls super. Following the inheritance chain, Ruby reaches BasicObject#method_missing, which raises NoMethodError.
Important: super here calls the next implementation of method_missing specifically.
Refinements: beyond the ancestor chain
The chains shown above describe the normal method lookup. Active refinements can additionally influence which implementation is chosen.
Refinements allow you to locally extend or override methods of existing classes without changing their global behavior.
ruby
class Post
def hello
"Hello from Post"
end
end
module PostRefinements
refine Post do
def hello
"Hello from refinement"
end
def goodbye
"Goodbye from refinement"
end
end
end
class ReplyPost < Post
end
module Example
using PostRefinements
post = Post.new
reply = ReplyPost.new
post.hello # => "Hello from refinement"
post.goodbye # => "Goodbye from refinement"
reply.hello # => "Hello from refinement"
reply.goodbye # => "Goodbye from refinement"
end
Post.new.hello # => "Hello from Post"
Post.new.goodbye # => NoMethodError
Post.ancestors
# => [Post, Object, Kernel, BasicObject]
What's happening here?
Postdefines a regularhellomethod.PostRefinementscontains two alternative implementations: an overriddenhelloand a newgoodbye.- Inside the lexical scope where
using PostRefinementsis activated, Ruby takes the refinement into account when looking up methods forPostand its subclass instances. - Outside that scope, the refinement methods are not accessible via a normal call.
- Notably,
PostRefinementsdoes not appear inPost.ancestors: a refinement does not attach a module to the class the wayincludeorprependdo.
Thus, a method doesn't necessarily need a regular position in the ancestors chain for Ruby to be able to call it. Refinements add another factor to method resolution — the lexical context in which the calling code is defined.
Conclusion
In Ruby, methods are not stored separately in each ordinary object. They are defined in classes, modules, and singleton classes.
And here it's important to separate two questions:
- Where is a method defined? — the illustration shows this.
- How does Ruby find the right method? — the lookup chains explain this.
It is precisely the combination of these mechanisms that makes Ruby's object model so flexible.