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 .
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:
or even
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.