extending self in a module

What does this code do.

module Say
 extend self
end

One of the characteristics of module is that you can’t make an instance of it. This will fail.

Say.new

However you can invoke a method on a module.

module Say
  def self.drink
    puts 'drinking'
  end
end
Say.drink

You can’t invoke an instance method of a module from a module. This will not work.

module Say
  def bark
    puts 'barking'
  end
end
Say.bark #=> undefined method ‘bark’ for Say:Module

However using extend self, method bark can be made available to module Say.

module Say
  def bark
    puts 'barking'
  end
  extend self
end
Say.bark #=> 'barking'

Statement extend self is an executable statement. When module is being loaded then self if the moduel itself. So that’s like saying extend Say. And that’s what happens. When a module extends another module then first module gets to invoke all the instance methods of the other module. That’s how in this case Say module is able to invoke method bar .

Comments

You should rather use module_function instead of extend self

Instance methods of modules are only available if the module is included somewhere. If you include the module into its own singleton class (via extend), then I think it's safe to assume the modules methods use no facilities of the object it is attached to (doesn't refer to self or any instance variables). In other words, it pretends to be a function.
Since such a (pseudo-) function is of no use for the user of an object, it'll just pollute the namespace. That can be avoided by making the method private. But you can't do that if you extend self - the method would be private there too, YourModule.method would raise a NoMethodError.

The clean solution to it is module_function. It makes your method available via a public YourModule.foo and makes the instance method private.