Ruby extend Method
last modified October 18, 2026
This tutorial explains how to use Ruby's extend method to add
module functionality to objects. The extend method is a powerful
way to mix in module methods at the object level.
The extend method adds a module's instance methods to the receiver's
singleton class. Unlike include, which adds methods to a class's
ancestor chain for all instances, extend changes only the receiver's
singleton class. For an ordinary object, the methods are available only on that
object. When the receiver is a class, the methods become class methods, and
subclasses inherit them through the singleton class chain.
This makes extend useful for adding functionality to a single
ordinary object without changing its class. Multiple modules can be extended,
and the order affects method lookup.
Basic extend Example
This simple example demonstrates how to extend an object with module methods. The methods become available on that specific object only.
module Greeter
def greet
"Hello from #{self.class}"
end
end
obj = Object.new
obj.extend(Greeter)
puts obj.greet # Hello from Object
The extend method adds Greeter module methods to
obj. Now obj can call greet even though
its class doesn't include this method. Other objects of the same class won't
have this method.
Extending Class Objects
Since classes are objects in Ruby, we can extend them with module methods. This makes the methods available as class methods rather than instance methods.
module ClassMethods
def class_info
"Class name: #{name}"
end
end
class MyClass
extend ClassMethods
end
puts MyClass.class_info # Class name: MyClass
Here extend adds class_info as a class method to
MyClass. This is a common pattern for adding class-level
functionality. The method becomes available on the class itself, and subclasses
also inherit it.
Multiple Module Extension
Multiple modules can be extended onto an object. When methods have the same name, the order in which the modules are inserted determines which method wins.
module A
def identify
"From module A"
end
end
module B
def identify
"From module B"
end
end
obj1 = Object.new
obj1.extend(A, B)
puts obj1.identify # From module A
obj2 = Object.new
obj2.extend(A)
obj2.extend(B)
puts obj2.identify # From module B
A single extend(A, B) call inserts the modules in reverse order, so
A takes precedence. Separate calls add each module on top of the
previous one, so the last call wins. The module found first in the singleton
class's ancestor chain is the one Ruby calls.
Singleton Class and Method Lookup
The extended methods live in the receiver's singleton class. Methods defined directly on that singleton class take precedence over methods from extended modules.
module Greeter
def greet
"Hello from module"
end
end
obj = Object.new
obj.extend(Greeter)
def obj.greet
"Hello from singleton method"
end
puts obj.greet
puts obj.singleton_class.ancestors.include?(Greeter) # true
The output is Hello from singleton method followed by
true. The singleton class itself comes before the extended module
in the lookup order, so its own method wins.
Extending Inside Classes
The extend method can be used inside class definitions to add
module methods to the class object itself. This is different from include.
module InstanceMethods
def instance_identify
"Instance method"
end
end
module ClassMethods
def class_identify
"Class method"
end
end
class MyClass
include InstanceMethods
extend ClassMethods
end
puts MyClass.class_identify
puts MyClass.new.instance_identify
This example shows the difference between include and
extend. include adds instance methods, while
extend adds class methods. Both are useful in different scenarios.
Dynamic Extension
Objects can be extended dynamically at runtime. This allows for flexible object behavior modification based on program conditions.
module AdminFeatures
def admin_action
"Performing admin action"
end
end
module UserFeatures
def user_action
"Performing user action"
end
end
class User
attr_accessor :role
end
user = User.new
user.role = :admin
user.extend(AdminFeatures) if user.role == :admin
user.extend(UserFeatures) if user.role == :user
puts user.admin_action if user.role == :admin
The user object is extended with different modules based on its role. This pattern enables role-specific functionality without subclassing. The methods only exist on objects that need them.
Extending Core Objects
Ruby's core objects can be extended with custom methods. This should be done judiciously to avoid conflicts and confusion.
module StringExtensions
def shout
upcase + "!"
end
end
str = "hello world"
str.extend(StringExtensions)
puts str.shout
puts "another string".respond_to?(:shout) # false
Only the specific str object gets the shout method.
Other strings remain unaffected. This is safer than monkey-patching the
String class directly. It limits the scope of changes.
Extend vs Include
This example contrasts extend and include to clarify
their different behaviors. They serve related but distinct purposes.
module SharedMethods
def identify
"From SharedMethods"
end
end
class ExtendedClass
extend SharedMethods
end
class IncludedClass
include SharedMethods
end
puts ExtendedClass.identify
puts IncludedClass.new.identify
ExtendedClass gets identify as a class method, while
IncludedClass gets it as an instance method. For the extended
class, the module sits in the singleton class; for the included class, it sits
in the class's ancestor chain.
Source
Ruby Object#extend Documentation
This tutorial covered Ruby's extend method with practical examples
showing object extension, class methods, method lookup, and dynamic behavior
modification.
Author
List all Ruby tutorials.