Как вы можете отслеживать полную последовательность и порядок 'require's в приложении Ruby в виде дерева? - PullRequest
7 голосов
/ 18 июня 2009

Как вы можете отобразить иерархию требований, которые имеют место в приложении Ruby?

Для некоторых файлов требуются файлы, требующие дополнительных файлов.

Однако, запустив приложение в режиме отладки, вы запускаете только подмножество необходимых файлов - только те, которые используются любым подмножеством функций, которые ваше приложение использует в любой данный момент времени.

Как вы можете отобразить полную иерархию всех требований в приложении в виде дерева?

1 Ответ

10 голосов
/ 18 июня 2009

Проблема в том, что в режиме разработки все файлы загружаются с 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

Есть способ избавиться от этого безумия.

...