为什么在 Ruby 中包含模块的顺序会有所不同?

Gar*_*eth 2 ruby module include

这个问题最好用代码示例来总结:

module TestOne
  module Foo
    def foo
      42
    end
  end

  module Bar
    include Foo
  end

  class Quux
    include Bar
  end
end

TestOne::Bar.ancestors # => [TestOne::Bar, TestOne::Foo]
TestOne::Quux.ancestors # => [TestOne::Quux, TestOne::Bar, TestOne::Foo, Object, Kernel]
TestOne::Quux.new.foo # => 42

module TestTwo
  class Quux
  end

  module Bar
  end

  module Foo
    def foo
      42
    end
  end
end

TestTwo::Quux.send :include, TestTwo::Bar
TestTwo::Bar.send :include, TestTwo::Foo

TestTwo::Bar.ancestors # => [TestTwo::Bar, TestTwo::Foo]
TestTwo::Quux.ancestors # => [TestTwo::Quux, TestTwo::Bar, Object, Kernel]
TestTwo::Quux.new.foo # => 
# ~> -:40: undefined method `foo' for #<TestTwo::Quux:0x24054> (NoMethodError)
Run Code Online (Sandbox Code Playgroud)

我认为当你包含一个模块(例如Bar在一个类中)时,Ruby 存储的所有内容都是包含的Foo事实。因此,当您调用 Foo 上的方法时,它会查找该方法。FooBarBar

如果这是真的,那么在调用时TestTwo::Quux.new.foo我已经将该foo方法混合进去了TestTwo::Bar,所以它应该可以工作,对吗?

Mat*_*rke 5

文档说append_features(由include调用)将方法混合到调用者中。因此,当TestTwo::Quux包含时TestTwo::Bar,不会添加任何方法TestTwo::Quux。下一行将方法添加到TestTwo::Bar,但不添加到TestTwo::Quux