Почему порядок включения модулей имеет значение в Ruby?

Этот вопрос лучше всего резюмировать на примере кода:

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, так что он должен работать, верно?

Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
0
1 278
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Это позор, потому что в моем реальном случае первое включение происходит вне моего контроля, я просто пытаюсь смешать что-то со всем, что включает мой целевой модуль. Ну что ж, спасибо :)

Gareth 03.12.2008 16:49

Другие вопросы по теме