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

Seems like you meant to write Say.new, not new Say in your “this will fail” example.

Also, while extend self is useful for complex cases, ruby also has module_function directive. IIRC, the only difference is that extend self respects method visibility.

@hakunin

Thanks for pointing that out. I wrote this blog when I was doing a log of JavaScript work. I guess I got new Say and Say.new mixed up.

I fail to see why this is a problem – surely you never want an “instance of a module”, rather you use the modules as mixins to your classes:

class Something
  extend Say
end

Something.bark

or even

class Something
  include Say
end

Something.new.bark

Those seem like more logical use cases for modules for me, where you have common functionality that you want to include without using class inheritance.

Post a new comment




Wrap code in <pre> ... </pre>

My name is Neeraj. You can contact me at neerajdotname@gmail.com . I am also on twitter , facebook and Linkedin .

admin_data , active_record_no_table , session_expiration_management , always_at_bottom and javascript_lab are some of my projects on github .