Edited at

Gemを作る時知っておくと役に立つかもしれない、lazy_load_hooksと主要なスコープについて

More than 1 year has passed since last update.

ActiveSupportはrailsの開発に役立つAPIを提供しているモジュールですが、その中にあるlazy_load_hooksという遅延処理に関連するモジュールについての記事です。


はじめに

ちまたに公開されてるgemを読んでいると、ActiveSupport.on_load :scope という記述をよく見かけます。対象スコープとなるモジュールが読み込まれた後でblockに渡した処理を遅延実行できる便利なものという認識です。

ですがいざ自分でgemを作ろうと思ったときに、on_loadで使えるスコープってどうなってるのかわからなかったので調べました、railsについてもう少し詳しく知りたい人や自分でgemを公開したい人向けかもしれません。


active_support/lazy_load_hooksについて

ソースコード

下記2つのインスタンス変数と3つのdefで読み込み、実行管理をしています。

run_load_hooksにて@loadedにkey,valueで対象スコープとそれに対応するnameを登録、on_loadedにて@load_hooksにて対象スコープnameと実行処理を登録します。on_loadでは対象スコープが@loadedに存在すれば即時実行、そうでなければrun_load_hooksにて@loadedに対象スコープが追加された後に、@load_hooksにスタックされた処理が遅延実行となります。


対象スコープ

最低限のrails生態系周りで登録されているスコープは以下の通り。


action_view/base.rb

ActiveSupport.run_load_hooks(:action_view, self)



active_job/base.rb

ActiveSupport.run_load_hooks(:active_job, self)



active_record/base.rb

ActiveSupport.run_load_hooks(:active_record, Base)



action_controller/base.rb

ActiveSupport.run_load_hooks(:action_controller, self)



action_mailer/base.rb

ActiveSupport.run_load_hooks(:action_mailer, self)



action_support/i18n.rb

ActiveSupport.run_load_hooks(:i18n)



web-console-x/**/web_console.rb

ActiveSupport.run_load_hooks(:web_console, self)



rails-x/**/configuration.rb

# First configurable block to run. Called before any initializers are run.

def before_configuration(&block)
ActiveSupport.on_load(:before_configuration, yield: true, &block)
end

# Third configurable block to run. Does not run if +config.cache_classes+
# set to false.
def before_eager_load(&block)
ActiveSupport.on_load(:before_eager_load, yield: true, &block)
end

# Second configurable block to run. Called before frameworks initialize.
def before_initialize(&block)
ActiveSupport.on_load(:before_initialize, yield: true, &block)
end

# Last configurable block to run. Called after frameworks initialize.
def after_initialize(&block)
ActiveSupport.on_load(:after_initialize, yield: true, &block)
end



対象スコープとなるオブジェクトの実行順

最後に参考までに上記オブジェクトのrun_load_hooks実行順です、lazy_load_hooksに直にnameを出力する記述を差し込みrails sしただけです。


  1. :i18n

  2. :active_record

  3. :action_view

  4. :web_console

  5. :before_configuration

  6. :before_initialize

  7. :before_eager_load

  8. :after_initialize

  9. :action_mailer

:action_controllerと:active_jobは別途controllerとjobが実行されるタイミングで動きます。


以上

以上になります。