🐕

Ruby の require と $LOADED_FEATURES

に公開

Ruby では別の Ruby スクリプトファイルを呼び出すときに require メソッドを利用してそのファイルを読み込みます。

# csv を読み込んで機能が利用できる状態にする
require "csv"

この require メソッドなのですが通常は1度読み込まれた Ruby のスクリプトファイルは2度読み込まれることはありません。

# 1度目のみ csv ファイルが読み込まれる
require "csv"

# いずれかのタイミングでもう一度 require されても csv が再度読み込まれることはない
require "csv"

また require

  • 読み込みを行った場合は true
  • 読み込みを行わなかった場合は false

を返します。

pp require "csv" # => true
pp require "csv" # => false

$LOADED_FEATURES

$LOADED_FEATURESrequire でロードされたファイル名の配列になります。

pp $LOADED_FEATURES
# => ["enumerator.so",
#     "thread.rb",
#     "fiber.so",
#     "rational.so",
#     "complex.so",
#     "ruby2_keywords.rb",
#      ...
#    ]

require されるとこの配列にそのファイル名が追加されます。

# require 前は含まれないが
pp $LOADED_FEATURES.any? { _1 =~ /csv/ }
# => false

require "csv"

# require 後には require したファイルが含まれるようになる
pp $LOADED_FEATURES.any? { _1 =~ /csv/ }
# => true

$LOADED_FEATURES から要素を削除するとどうなる?

$LOADED_FEATURES から特定の要素を削除すると『それがまだ require されていない』ような振る舞いになります。

require "csv"

# 2回目はロードされない
pp require "csv" # => false

# $LOADED_FEATURES から csv 関連のファイルを削除する
$LOADED_FEATURES.reject! { _1 =~ /csv/ }

# csv が再度ロードされる
pp require "csv" # => true

こんな感じで強制的に再度 require してファイルが読み込まれます。
Rails の Zeitwerk はこの仕組みを利用して再ロードを実現しています。

参照

GitHubで編集を提案

Discussion