Skip to content
Go back

Module Functions in Ruby: module_function vs extend self

Updated:
Module Functions in Ruby: module_function vs extend self

In Ruby, Modules are a way of grouping together methods, classes, and constants with two major benefits:

A module can also serve as a collection of utility methods (functions) that can be called either:

# 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:

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


You might also like


Share this post on:

Previous Post
Migrating from Gridsome to Astro: A Developer Journey
Next Post
Re-initializing Table Sequences in PostgreSQL