extend self in a module

mar*_*rie 1 ruby ruby-on-rails

It seems that this two pieces of codes do the same job, but I would like to understand why I'd rather use one or another

First example:

module MyModule 
  extend self

  def first_method
  end

  def second_method
  end

end
Run Code Online (Sandbox Code Playgroud)

Second example:

module MyModule 

  def self.first_method
  end

  def self.second_method
  end

end
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 7

Your first example defines two instance methods and makes them also available as class (or module) methods via extend:

module MyModule 
  def first_method; end
  def second_method; end
end

MyModule.instance_methods         #=> [:second_method, :first_method]
MyModule.methods - Module.methods #=> []

MyModule.extend MyModule

MyModule.instance_methods         #=> [:second_method, :first_method]
MyModule.methods - Module.methods #=> [:second_method, :first_method]
Run Code Online (Sandbox Code Playgroud)

Whereas your second example just defines two class (or module) methods and no instance methods:

module MyModule 
  def self.first_method; end
  def self.second_method; end
end

MyModule.instance_methods         #=> []
MyModule.methods - Module.methods #=> [:second_method, :first_method]
Run Code Online (Sandbox Code Playgroud)

The first variant can be useful when you want to provide some utility functions that can be called as:

MyModule.first_method
Run Code Online (Sandbox Code Playgroud)

or be included in other modules / classes:

class Foo
  include MyModule

  def another_method
    first_method     # <- no explicit receiver needed
  end
end
Run Code Online (Sandbox Code Playgroud)

Ruby also provides the helper method module_function to define methods that way:

module MyModule
  def first_method
  end
  module_function :first_method
end
Run Code Online (Sandbox Code Playgroud)

It adds the method as a class methods and makes the instance method private. It's how the methods in Kernel work.