Ruby prepend Method
last modified April 27, 2025
This tutorial explains how to use Ruby's prepend
method. This
powerful module inclusion method alters method lookup order in classes.
The prepend method inserts a module before the class in the
ancestor chain. This means module methods override class methods with the
same name. It's the opposite of include
.
Prepending is useful for method overriding, decoration, and aspect-oriented programming. It allows clean separation of concerns while modifying behavior. Multiple prepends stack in reverse order.
Basic prepend Example
This simple example demonstrates how prepend changes method lookup order. The module method takes precedence over the class method.
module Greeter def greet "Hello from module!" end end class Person prepend Greeter def greet "Hello from class!" end end puts Person.new.greet
The output shows the module's method is called, not the class's. This happens because prepend puts Greeter before Person in the ancestor chain.
Multiple prepend Calls
When multiple modules are prepended, they are inserted in reverse order. The last prepended module appears first in the ancestor chain.
module A def greet "A says: #{super}" end end module B def greet "B says: #{super}" end end class Person prepend A prepend B def greet "Hello!" end end puts Person.new.greet puts Person.ancestors
The output shows B's method calls A's, which calls the original. The ancestors list shows B comes before A, which comes before Person.
prepend vs include
This example contrasts prepend with include. Include puts modules after the class in the ancestor chain, while prepend puts them before.
module M def greet "Module says: #{super}" end end class Included include M def greet "Class says hello!" end end class Prepended prepend M def greet "Class says hello!" end end puts "Include: #{Included.new.greet}" puts "Prepend: #{Prepended.new.greet}" puts "Included ancestors: #{Included.ancestors}" puts "Prepended ancestors: #{Prepended.ancestors}"
With include, the class method wins. With prepend, the module method wins. The ancestors output shows the different method lookup orders.
Using super with prepend
The super
keyword works naturally with prepend, allowing chained
method calls. This enables powerful method decoration patterns.
module Logging def save puts "Logging before save" super puts "Logging after save" end end class Document prepend Logging def save puts "Saving document..." end end Document.new.save
The Logging module wraps the original save method, adding behavior before and after. This is a common prepend use case for cross-cutting concerns.
prepend for Method Overriding
prepend can override methods from parent classes, not just the current class. This example shows overriding an inherited method.
class Animal def speak "Animal sound" end end module Loud def speak "#{super.upcase}!!!" end end class Dog < Animal prepend Loud def speak "Woof" end end puts Dog.new.speak puts Dog.ancestors
The Loud module overrides both Dog's speak and Animal's speak. The output shows the module's version is called first, which can then call super.
Dynamic prepend
prepend can be called at runtime, not just during class definition. This allows dynamic modification of behavior.
module AdminFeatures def access "Admin access granted" end end class User def access "Regular user access" end end user = User.new puts user.access User.prepend(AdminFeatures) puts user.access
After prepending AdminFeatures, even existing instances get the new behavior. This demonstrates Ruby's dynamic nature and prepend's runtime effects.
prepend in Real-world Use
This example shows a practical use case for prepend - adding caching to an expensive calculation without modifying the original class.
module Cache def calculate @cache ||= {} @cache[inputs] ||= super end def inputs [@x, @y] end end class Calculator prepend Cache def initialize(x, y) @x = x @y = y end def calculate puts "Performing expensive calculation..." @x * @y end end calc = Calculator.new(5, 10) puts calc.calculate puts calc.calculate
The Cache module transparently adds memoization. The second calculate call returns the cached result without recalculating. The original Calculator remains unchanged.
Source
Ruby Module#prepend Documentation
This tutorial covered Ruby's prepend method with practical examples showing method overriding, decoration, and dynamic behavior modification.
Author
List all Ruby tutorials.