Почему автозагрузка, load_all! и потребуйте всех используемых в active_support.rb?

Одна вещь, которую следует учитывать, - , почему у вас так много предложений. Подобно тому, как операторы SWITCH часто указывают на то, что вы должны перемещать варианты выбора в подклассы, большая сложная цепочка операторов IF может указывать на то, что вы объединяете слишком много концепций (и, следовательно, решений) в одном месте.

В качестве примера я буду использовать пример расчета комиссии. В одной из построенных мною комиссионных ставок зависит от суммы комиссионных, выплачиваемых оптовику, который передает часть розничному продавцу. Сумма, передаваемая от оптовика к розничному продавцу, зависит от конкретного соглашения между розничным продавцом и оптовым продавцом (на основании договора). Количество, которое оптовик получает, также зависит от продуктовой линейки, конкретного продукта и количества проданного продукта.

Помимо этого, существовали дополнительные правила «исключений», основанные на состоянии клиента, конкретных настройках продукта и т. Д. Все это можно разработать в сложной цепочке операторов IF, но вместо этого мы сделали управляемые данными приложения.

Поместив всю эту информацию в таблицы, мы смогли выполнить правила данных. Сначала срабатывают общие правила оптовика, а затем срабатывают любые правила переопределения. Затем, имея в своем распоряжении комиссию базового оптовика, мы заставим оптовика распространять общие правила розничного предприятия, а затем исключения из них.

Это превратило огромный шарик логики в простой четырехэтапный процесс, при котором каждый шаг просто выполнял запрос к базе данных, чтобы найти правильное правило для применения.

Это, конечно, может не применяться в вашей ситуации, но часто такой большой комплекс действительно означает, что либо недостаточно классов, разделяющих ответственность (еще одним решением нашей проблемы могли быть фабричные классы, которые содержали конкретные правила и переопределения), или функциональность должна управляться данными.

10
задан monkeyman 18 June 2009 в 15:40
поделиться

2 ответа

Я не знаю точно, почему Rails использует три разных метода загрузки (на самом деле два - см. Ниже). Но в целом я знаю, почему кто-то может.

Требовать означает «загрузить это прямо сейчас». автозагрузка означает «загрузить это, когда вам нужно его использовать». Обычная причина использования обоих состоит в том, что у вас есть файлы, которые, как вы в значительной степени предполагаете, будут использоваться при каждом вызове программы; и другие, которые не являются обязательными. Например, в приложении Rails, которое не использует устаревшие методы, вам никогда не понадобится Deprecation ; Так зачем же замедлять начальную настройку, загружая этот файл?

В других случаях вы можете различать файлы, которые понадобятся на ранней стадии выполнения программы, и файлы, которые могут ждать. Например, вы Gzip вряд ли понадобится до тех пор, пока не поступит первый запрос. Таким образом, используя автозагрузку, вы можете сократить время начальной настройки за счет небольшого замедления для первого запроса.

Вы может спросить, а почему бы просто не использовать автозагрузку для всего? Зачем загружать что-нибудь до того, как это абсолютно необходимо? Одна из причин заключается в том, что автозагрузка работает только для констант. Так, например, active_support / core_ext добавляет к Numeric набор методов, чтобы вы могли написать такой код, как 3.days , 6.minutes и ] 16.seconds.ago . В 3.days нет константы, поэтому вы не можете запустить автозагрузку для этого выражения. (И вы не можете автозагрузить Numeric , потому что базовый класс уже был загружен - это ' просто расширения, которые вы хотите добавить.)

Наконец, этот класс фактически не использует три метода загрузки; он использует два и предоставляет один (вроде). load_all! используется Rails :: Initializer с до

 # Предварительно загрузить все фреймворки, указанные в Configuration # frameworks.
# Используется пассажиром, чтобы убедиться, что все загружено перед разветвлением и
# чтобы избежать условий гонки автозагрузки в JRuby.

Я не знаю подробностей и не знаю, почему предварительно загружены именно эти модули (а не другие). Но поскольку это предназначено для поддержки определенных сред, вы можете понять, почему для этого может потребоваться код, отдельный от механизма загрузки по умолчанию.

16
ответ дан 3 December 2019 в 21:22
поделиться

Рубиновый метод автозагрузки может использоваться для связывания константы с имя файла, которое будет загружено при первой ссылке на указанную константу. Это избавляет вас от необходимости загружать всю структуру при запуске.

Похоже, что метод load_all! вызывается из rails initializer.rb , и используется для предварительной загрузки всех фреймворков, которые настроены для предварительной загрузки. Это работает путем вызова каждого метода frameworks load_all! , который просто ссылается на массив констант ... который запускает автозагрузку.

Согласно комментариям в initializer.rb для preload_frameworks ...

# Preload all frameworks specified by the Configuration#frameworks.
# Used by Passenger to ensure everything's loaded before forking and
# to avoid autoload race conditions in JRuby.

Требование заключается в загрузке основных необходимых файлов для конкретной платформы.

1
ответ дан 3 December 2019 в 21:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: