开发者

why do people use extend in a module definition?

开发者_运维百科

for example, the rubygem Devise has the following piece of code in lib/devise/controllers/helpers.rb

    module Helpers
      extend ActiveSupport::Concern

why use extend here? Will include do the same?


No, include will not do the same.

extend and include perform similar but distinct roles. include takes the instance methods of the included module and makes them available to instances of the including module. In effect, include inserts the included module as a superclass of the including (in fact, #ancestors will even show the included module).

extend, on the other hand, adds the methods of the named module to the receiver. In the case of calling extend during a module definition, that means that the "extended" module's instance methods will become class methods of the "extending" module. It's often used to import decorators (really just calls to class methods) into a class or module being defined.

So, in brief, the snippet above will take the instance methods of ActiveSupport::Concern and make them class methods of Helpers.


Basically, Object#extend is just:

class Object
  def extend(*ms)
    ms.each do |m|
      class << self
        include m # Obviously, this won't work since m isn't in scope
      end
    end
  end
end

So, it's easy to see that they are obviously not the same, since the methods end up in different classes.


A working, but less obvious version of Object#extend would be:

class Object
  def extend(*ms)
    ms.each do |m|
      singleton_class.send :include, m # Because Module#include is private
    end
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜