
Module Functions in Ruby: module_function vs extend self
ruby modules
In Ruby, Modules are a way of grouping together methods, classes, and constants with two major benefits:
- Provide namespacing and prevent name collisions.
- Implement the mixin facility, letting you add functionality to classes in a controlled way.
A module can also serve as a collection of utility methods (functions) that can be called either:
- With the module as the receiver (
MyModule.some_method
) - Or mixed into a class (
include MyModule
) so they’re available as instance methods.
# class-level call
MyModule.some_method
# instance-level call
include MyModule
some_method
There are multiple techniques to achieve this in Ruby, but the most common are Module#module_function
and extend self
.
Using module_function
module_function
turns a method into both:
- A private instance method (when included in a class).
- A public module method (callable on the module itself).
module MyModule
def some_method
puts "MyModule#some_method"
end
module_function :some_method
end
Equivalent to:
module MyModule
def self.some_method
"MyModule#some_method"
end
private
def some_method
"MyModule#some_method"
end
end
You can also make all subsequent methods module functions:
module MyModule
module_function
def some_method
"MyModule#some_method"
end
end
Method visibility
MyModule.public_method_defined?(:some_method) # => false
MyModule.private_method_defined?(:some_method) # => true
MyModule.method(:some_method).owner.singleton_class? # => true
module_function
makes copies of methods — meaning the module’s copy and the instance’s copy can diverge if redefined later.
Using extend self
Another approach is extend self
. This makes all instance methods also available as module methods.
module MyModule
extend self
def some_method
"MyModule#some_method"
end
end
Method visibility
MyModule.public_method_defined?(:some_method) # => true
MyModule.method(:some_method).owner.singleton_class? # => false
Here, no method copies are made — the same method is available both on the module and when included in a class.
Key Differences
Feature | module_function | extend self |
---|---|---|
Method visibility when included | Private | Public |
Creates method copies? | Yes | No |
API stability | Avoids leaking methods into including classes | Extends class’s API directly |
When to use | Utility functions you don’t want in class’s public API | Utility functions meant to be public in both contexts |
Wrap-up
- Use module_function if you want to define module-level utility functions that shouldn’t become part of a class’s public API.
- Use extend self if you want the same methods to be available both at the module level and when mixed into classes.
- Both patterns are widely used; which one you choose depends on API design intent.