Как вы можете отслеживать полную последовательность и порядок запросов в приложении Ruby в виде дерева?
-
06-07-2019 - |
Вопрос
Как вы можете отобразить иерархию требований, которые выполняются в приложении Ruby?
Для некоторых файлов требуются файлы, для которых требуются дополнительные файлы.
Однако, запуская приложение в режиме отладки, вы запускаете только подмножество необходимых файлов - только те, которые используются любым подмножеством функций, используемых вашим приложением в любой данный момент времени.
Как вы могли бы отобразить полную иерархию всех требований в приложении в виде дерева?
Решение
Проблема в том, что в режиме разработки все файлы загружаются с load
вместо того , чтобы require
чтобы их можно было перезагружать при каждом запросе.В процессе производства они загружаются только один раз.За исключением некоторых классов framework, большинство файлов по-прежнему загружаются только при первом использовании.Это происходит потому, что 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
Удачи вам
Редактировать:Объяснение
Что это делает, так это создает глобальный массив для хранения уровня вложенности requireds.Первый put выводит требуемый файл.Затем к уровню вложенности добавляется прочерк.Затем файл действительно требуется.Если требуются вызовы загруженного файла, то весь этот процесс запускается снова, за исключением того, что уровень вложенности равен 1, поэтому "-#{file}" помещается-ed.Этот процесс повторяется, за исключением того, что по мере роста уровня вложенности растут и тире.После загрузки файла и всех его зависимостей require удаляет добавленную им черту, так что уровень вложенности находится в том же состоянии, в котором он находился при запуске require.Это позволяет сохранить древовидную структуру точной.
const_missing аналогичен method_missing.В принципе, точно так же, как когда вы звоните AnObject.some_unknown_method
руби позвонит AnObject.method_missing(:some_unknown_method)
перед вызовом Nometoderror использование SomeUnknownConstant запускает const_missing(:SomeUnknownConstant)
перед вызовом NameError.Rails определяет const_missing таким образом, что он будет искать определенные указанные пути для файлов, которые могут определять отсутствующую константу.Он использует соглашение об именовании для облегчения этого, например SomeUnknownConstant
ожидается, что он будет находиться в some_unknown_constant.rb
У большей части этого безумия с rails есть свой метод.