2

フックに関する記事があります。ActiveSupport::ConcernRails での実用的な実装は次のとおりです。

module ActionController
  class Base < Metal
    include AbstractController::Layouts
  end
end

module AbstractController
  module Layouts
    extend ActiveSupport::Concern

    include Rendering

    included do
      class_attribute :_layout, :_layout_conditions, :instance_accessor => false
      self._layout = nil
      self._layout_conditions = {}
      _write_layout_method
    end

    module ClassMethods
      ...
    end
  end
end

module AbstractController
  module Rendering
    extend ActiveSupport::Concern

    included do
      class_attribute :protected_instance_variables
      self.protected_instance_variables = []
    end

    module ClassMethods
      ...
    end
  end
end

ruby フックの前にextend呼び出しはどのようにLayouts実行されますか? を最初に実行する必要がありますappend_featuresextend結局、要点はappend_featuresRuby のデフォルトをハイジャックして再実装することです。ただし、Ruby のドキュメントによると、このモジュール (eg ) を別のモジュール (eg ) にappend_featuresインクルードした直後に が実行されます。だから私には混乱があります。その場合、上書きされたofは呼び出されません。AbstractController::LayoutsActionController::Baseappend_featuresActiveSupport::Concern

4

1 に答える 1

1

これが私の見解です:

「インクルード」は、モジュールをパラメーターとして受け取るメソッドのように考えることができます。モジュールを含めるには、モジュールが環境によって既にロードされている必要があります。そうしないと、一定のエラーが発生して回線が失敗します。

したがって、これが機能するためには、include AbstractController::Layoutsが呼び出されたときに、AbstractController または最上位の名前空間にレイアウトをロードする必要があります。

actionpack のソース コードを調べると、Layoutsが autoloadedであることがわかります。これにより、「include」行が完了する前に確実にロードされるようになります。

extend ActiveSupport::Concernは Layoutsのロード時に実行されるため、append_featuresオーバーライドはActionController::Base の「include」行の実行が完了するまでに使用可能になります。

この後、ActionController::Base を引数として Layouts の append_features メソッドが実行されます。

于 2012-09-24T13:29:35.373 に答える