Проблема в том, что в режиме разработки все файлы загружаются с load
, а не require
, чтобы их можно было перезагружать при каждом запросе. В производство они загружаются только один раз. За исключением некоторых классов инфраструктуры, большинство файлов по-прежнему загружаются только при первом использовании. Это происходит потому, что ActiveSupport переопределяет const_missing для автоматической попытки загрузки неизвестных констант из файлов с соответствующей схемой именования (ConstantName.to_s.underscore
даст require 'constant_name'
). Это, конечно, действительно запутывает иерархию «требовать».
В простейшем случае вы можете изменить следующее, чтобы удовлетворить некоторые ваши потребности (также проверьте зависимости в active_support)
$require_level = []
alias :orig_require :require
def require(file)
puts "#{$require_level.join}#{file}"
$require_level << "-"
r = orig_require(file)
$require_level.pop
r
end
require 'foo'
require 'baz'
ben@legba-2:~ $ ruby check_requires.rb
foo
-bar
baz
Удачи
РЕДАКТИРОВАТЬ: Объяснение
Что делает, так это создает глобальный массив для хранения уровня вложенности потребностей. Первый выводит вывод требуемого файла. Затем черта добавляется к уровню вложенности. Файл тогда фактически требуется. Если вызовы загруженных файлов требуют, тогда весь этот процесс начинается снова, за исключением того, что уровень вложенности равен 1 глубине, поэтому "- # {file}" ставится-ed. Этот процесс повторяется за исключением того, что уровень вложенности растет, как и тире. После загрузки файла и всех его зависимостей require снимает добавленную черту, чтобы уровень вложения находился в том же состоянии, в котором он был при запуске require. Это сохраняет структуру дерева точным.
const_missing похож на method_missing. По сути, так же, как при вызове AnObject.some_unknown_method
ruby вызовет AnObject.method_missing(:some_unknown_method)
перед вызовом NoMethodError, использование SomeUnknownConstant вызывает const_missing(:SomeUnknownConstant)
перед вызовом NameError. Rails определяет const_missing так, что он будет искать определенные пути для файлов, которые могут определить отсутствующую константу. Для этого используется соглашение об именах, например SomeUnknownConstant
ожидается в some_unknown_constant.rb
Есть способ избавиться от этого безумия.