Этот вопрос лучше всего резюмировать на примере кода:
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)
Я думал, что когда вы включаете модуль (например, Bar в класс Foo), все, что сохраняет Ruby, - это тот факт, что Foo включает Bar. Итак, когда вы вызываете метод в Foo, он ищет метод в Bar.
Если это правда, то к моменту вызова TestTwo::Quux.new.foo я смешал метод foo с TestTwo::Bar, так что он должен работать, верно?

В документах говорится, что append_features (который вызывается с помощью include) смешивает методы с вызывающим. Поэтому, когда TestTwo::Quux включает TestTwo::Bar, к TestTwo::Quux не добавляются никакие методы. Следующая строка добавляет методы к TestTwo::Bar, но не к TestTwo::Quux.
Это позор, потому что в моем реальном случае первое включение происходит вне моего контроля, я просто пытаюсь смешать что-то со всем, что включает мой целевой модуль. Ну что ж, спасибо :)