为什么/如何 ActiveSupport::Concern 改变祖先查找顺序?

jcm*_*jcm 2 ruby activesupport-concern

考虑以下代码:

require 'active_support/concern'

module Inner
end

module Outer
  extend ActiveSupport::Concern
  included do
    include Inner
  end
end

class FirstClass
  include Outer
end

module SecondInner
end

module SecondOuter
  include SecondInner
end

class SecondClass
  include SecondOuter
end
Run Code Online (Sandbox Code Playgroud)

为什么通过 AS::Concern 包含的模块的祖先顺序与普通的 Ruby 不同?

FirstClass.ancestors
# => [FirstClass, Inner, Outer, Object, PP::ObjectMixin, Kernel, BasicObject]

SecondClass.ancestors
# => [SecondClass, SecondOuter, SecondInner, Object, PP::ObjectMixin, Kernel, BasicObject]
Run Code Online (Sandbox Code Playgroud)

And*_*eko 5

ActiveSupport::Concern 不改变祖先查找顺序。

如果您将 更改module Outer为使用纯 Ruby 来执行相同的操作,那么 AS 在没有 AS 的情况下会做什么,您会看到它具有相同的祖先链:

module Outer
  def self.included(base)
    base.send(:include, Inner)
  end
end

SecondClass.ancestors
#=> [SecondClass, SecondOuter, SecondInner, Object, PP::ObjectMixin, Kernel, BasicObject]
Run Code Online (Sandbox Code Playgroud)