Question
In Ruby, if I monkey patch a method in a class, how can I still call the original implementation from the new method?
I am looking for something similar to super, but for a method that I redefine in the same class.
For example:
class Foo
def bar
"Hello"
end
end
class Foo
def bar
super() + " World"
end
end
Foo.new.bar # expected: "Hello World"
Is there a way to call the previous version of bar after reopening the class and redefining it?
Short Answer
By the end of this page, you will understand why super does not call the previous version of a monkey-patched method in the same Ruby class, and how to correctly preserve and call the original method using techniques like alias_method. You will also see safer patterns, common mistakes, and how this works in real Ruby codebases.
Concept
In Ruby, monkey patching means reopening a class and changing or replacing its methods. This is powerful, but it also means the new method definition usually replaces the old one.
A common beginner question is: If I redefine a method, can I still call the old version from the new one?
The key idea is:
supercalls a method with the same name in the ancestor chain- It does not call the method definition that was previously written in the same class
- When you redefine a method in the same class, the old definition is overwritten unless you save it first
So in this case:
class Foo
def bar
"Hello"
end
end
class Foo
def bar
super + " World"
end
end
super will look for bar in Foo's superclass, not for the earlier bar that used to exist in Foo itself.
That is why monkey patching often uses :
Mental Model
Think of a Ruby class like a whiteboard with method names written on it.
If Foo has a method named bar, the whiteboard says:
bar -> "Hello"
When you reopen the class and define bar again, you erase the old line and write a new one:
bar -> new implementation
The old writing is gone unless you copied it somewhere first.
Now think of super as walking upstairs to ask a parent class for help. It does not look at what was previously erased and rewritten on the same whiteboard. It only checks parent classes or included modules in the method lookup chain.
So:
- redefining a method in the same class = replacing the current label
super= ask the next ancestor, not the old version in the same classalias_method= make a backup copy before replacing it
Syntax and Examples
Basic pattern with alias_method
class Foo
def bar
"Hello"
end
end
class Foo
alias_method :bar_without_patch, :bar
def bar
bar_without_patch + " World"
end
end
puts Foo.new.bar
# Hello World
What this does
alias_method :bar_without_patch, :barsaves the originalbar- The new
barmethod replaces the old one - Inside the new
bar, you callbar_without_patch
Why super does not work here
class Foo
def bar
+
Step by Step Execution
Consider this example:
class Foo
def bar
"Hello"
end
end
class Foo
alias_method :original_bar, :bar
def bar
original_bar + " World"
end
end
result = Foo.new.bar
puts result
Step-by-step
- Ruby defines class
Foo - Method
baris created and returns"Hello" - Ruby reopens class
Foo alias_method :original_bar, :barcreates a second name for the currentbar- now both
barandoriginal_barrefer to the original implementation
- now both
- A new
barmethod is defined- this replaces the old
Real World Use Cases
Monkey patching with access to the original method appears in several real situations:
Logging and instrumentation
You may want to keep the original behavior but add logging.
class ApiClient
def fetch
"data"
end
end
class ApiClient
alias_method :original_fetch, :fetch
def fetch
puts "Fetching started"
result = original_fetch
puts "Fetching finished"
result
end
end
Fixing behavior in third-party code
Sometimes a gem has a bug and you need a temporary patch while still using most of its original method.
Adding validation
You can wrap an existing method with extra checks.
class User
def set_age(age)
@age = age
end
end
class User
alias_method :original_set_age,
()
, age <
original_set_age(age)
Real Codebase Usage
In real Ruby projects, developers usually try to avoid direct monkey patching unless necessary, but when they do use it, they often follow some patterns.
Preserve the original behavior
If the original method still matters, save it before redefining it:
alias_method :original_method_name, :method_name
Prefer prepend for cleaner extension
A common modern pattern is:
module Patch
def perform(*args)
puts "before"
result = super
puts "after"
result
end
end
SomeClass.prepend(Patch)
This is often easier to reason about than alias chains.
Use guard clauses
When wrapping a method, developers often validate inputs early:
def save(data)
return false if data.nil?
original_save(data)
Common Mistakes
Mistake 1: Expecting super to call the old method in the same class
Broken code:
class Foo
def bar
"Hello"
end
end
class Foo
def bar
super + " World"
end
end
Why it fails:
superlooks in ancestors- it does not call the earlier
barthat existed inFoo
Fix:
class Foo
alias_method :original_bar, :bar
def bar
original_bar + " World"
end
end
Mistake 2: Creating infinite recursion
Broken code:
Comparisons
super vs alias_method vs prepend
| Technique | What it calls | Best use case | Main limitation |
|---|---|---|---|
super | Same method in ancestor chain | Inheritance or modules | Does not call previous method in same class |
alias_method | Saved copy of original method | Direct monkey patching | Can become messy with multiple patches |
prepend | Original method through ancestor lookup | Cleaner wrapping/extending behavior | Requires using a module |
Redefining in same class vs subclassing
Cheat Sheet
Quick reference
super
def method_name
super
end
- Calls the same method in a superclass or prepended/included ancestor
- Does not call the old version of a method redefined in the same class
Save original method before monkey patching
class Foo
alias_method :original_bar, :bar
def bar
original_bar + " World"
end
end
Important rule
- Alias first, redefine second
With arguments
alias_method :original_greet, :greet
def greet(name)
original_greet(name) + "!"
end
Cleaner alternative with prepend
FAQ
Why does super not work when I redefine a method in the same Ruby class?
Because super only looks in the method lookup chain above the current class or module. It does not remember the old method body that was replaced in the same class.
How do I call the original method after monkey patching in Ruby?
Save it first with alias_method, then call the alias inside the new method.
Is alias_method better than super for monkey patching?
For redefining a method in the same class, yes. super is for ancestor methods, while alias_method lets you preserve the original implementation before replacing it.
What is the modern Ruby alternative to alias-based monkey patching?
Module#prepend is often preferred because it works naturally with super and keeps the method lookup chain clearer.
Can monkey patching be dangerous?
Yes. It changes behavior globally for that class in the current process, which can affect unrelated parts of an application.
Should I monkey patch a gem or Ruby core class?
Only when necessary. Prefer safer alternatives like wrappers, subclasses, composition, or prepend if they fit your use case.
Can I monkey patch instance methods and class methods the same way?
Mini Project
Description
Build a small Ruby class that formats messages, then monkey patch it to add a prefix while still keeping the original behavior. This demonstrates how to preserve an instance method before redefining it.
Goal
Create a monkey patch that extends an existing method without losing the original implementation.
Requirements
- Create a class with an instance method that returns a basic message.
- Preserve the original method before redefining it.
- Redefine the method so it adds extra text to the original result.
- Print the final result to confirm the patch works.
Keep learning
Related questions
Difference Between require and include in Ruby
Learn the difference between require and include in Ruby, when to load a file, and when to mix module methods into a class.
Fixing Ruby Gem Native Extension Errors: mkmf.rb Can't Find Header Files for Ruby
Learn why Ruby gem installs fail with missing ruby.h, how native extensions work, and how to fix header file errors on Linux servers.
How to Add One Array to Another in Ruby Without Creating a Nested Array
Learn how to combine arrays in Ruby without getting nested arrays or nil values. Understand push, concat, +, and flatten clearly.