2009年8月23日日曜日

[Rails][CodeReading] Rails::Initializer (6) set_autoload_paths

Initializer.process で6番目に呼ばれる set_autoload_paths メソッド。

def set_autoload_paths
ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq

extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
unless extra.empty?
abort <<-end_error
load_once_paths must be a subset of the load_paths.
Extra items in load_once_paths: #{extra * ','}
end_error
end

# Freeze the arrays so future modifications will fail rather than do nothing mysteriously
configuration.load_once_paths.freeze
end


Configuration.load_paths を、ActiveSupport::Dependencies.load_paths に、
Configuration.load_once_paths を、ActiveSupport::Dependencies.load_once_paths に
設定しています。

この ActiveSupport::Dependencies.load_paths がどう使われるかというと。

未知の定数が出てきたときに呼ばれる ActiveSupport::Dependencies.load_missing_constant の中で

# activesupport/lib/dependencies.rb
# Load the constant named +const_name+ which is missing from +from_mod+. If
# it is not possible to load the constant into from_mod, try its parent module
# using const_missing.
def load_missing_constant(from_mod, const_name)
~~ 略 ~~
qualified_name = qualified_name_for from_mod, const_name
path_suffix = qualified_name.underscore
name_error = NameError.new("uninitialized constant #{qualified_name}")

file_path = search_for_file(path_suffix)
~~ 略 ~~
end

と定数->ファイルパス(のsuffix)への変換が行われ(qualified_name.underscore)、search_for_file メソッドへとファイルパスが引き渡されるのですが、search_for_file で

# activesupport/lib/active_support/dependencies.rb
# Search for a file in load_paths matching the provided suffix.
def search_for_file(path_suffix)
path_suffix = path_suffix + '.rb' unless path_suffix.ends_with? '.rb'
load_paths.each do |root|
path = File.join(root, path_suffix)
return path if File.file? path
end
nil # Gee, I sure wish we had first_match ;-)
end

と load_paths と path_suffix をくっつけて(そのファイルが存在すれば)ロードすべきファイルのパスを返す、という仕組み。
この仕組みの詳細は『実践Rails』に詳しいです。

[Rails][CodeReading] Railsの初期化コードを読む (イントロ&目次)

0 件のコメント:

コメントを投稿