Module Functions in Ruby: module_function vs extend self

Module Functions in Ruby: module_function vs extend self


ruby modules
Last updated on

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

Featuremodule_functionextend self
Method visibility when includedPrivatePublic
Creates method copies?YesNo
API stabilityAvoids leaking methods into including classesExtends class’s API directly
When to useUtility functions you don’t want in class’s public APIUtility 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.

You might also like

© 2025 Syed Aslam