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 .
- Add new comment
- 1136 reads
- Feed: neeraj.name
- Original article


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.