У сучасних версіях Rails (починаючи з Rails 6) автозавантаженням керує Zeitwerk, завантажувач коду для Ruby. Zeitwerk є ефективним та потокобезпечним, розробленим для завантаження коду вашої програми за запитом. Ось як Rails використовує Zeitwerk для автозавантаження:
Ключові особливості Zeitwerk у Rails
- Конвенція замість конфігурації:
- Zeitwerk очікує, що імена файлів і класів/модулів будуть дотримуватись єдиної naming convention, де структура директорій відповідає ієрархії класів/модулів.
- Наприклад,
app/models/user.rb
має визначати класUser
, аapp/models/admin/user.rb
має визначати класAdmin::User
.
2. Попереднє завантаження (Eager Loading):
- У виробничому середовищі або в середовищах, де
config.eager_load = true
, Zeitwerk завантажує всі файли програми заздалегідь, щоб покращити продуктивність під час виконання.
3. Ліниве завантаження (Lazy Loading):
- У середовищах розробки та тестування файли завантажуються лише тоді, коли їхні константи вперше використовуються. Це мінімізує використання пам'яті та прискорює час запуску.
4.
**Перезавантаження (Reloading):
- Zeitwerk підтримує перезавантаження коду в режимі розробки, що безшовно інтегрується з монітором файлів Rails (
listen
gem). Це означає, що зміни у файлах відображаються без необхідності перезапускати сервер.
5. Потокова безпека (Thread Safety):
- Zeitwerk є потокобезпечним і розроблений для роботи в багатопотокових середовищах, що робить його надійним для одночасних Rails додатків.
6. Користувацькі шляхи автозавантаження (Custom Autoload Paths):
- Rails дозволяє налаштовувати шляхи автозавантаження, додаючи директорії до шляхів автозавантаження через
config.autoload_paths
. Zeitwerk потім керує цими директоріями.
Як це працює в Rails
- Ініціалізація:
- Під час процесу завантаження Rails, Zeitwerk конфігурується з шляхами автозавантаження (
app/models
,app/controllers
тощо) і керує завантаженням файлів у цих директоріях.
2. Відображення файлів на константи (File-to-Constant Mapping):
- Zeitwerk відображає шляхи файлів на константи, використовуючи naming convention.
Наприклад:
app/models/order.rb
→ Order
app/services/payment/processor.rb
→ Payment::Processor
3. Автозавантаження за запитом (Autoloading on Demand):
- Коли Ruby стикається з невизначеною константою, Zeitwerk перехоплює помилку
NameError
і перевіряє своє внутрішнє відображення. Якщо файл, що визначає константу, існує, Zeitwerk завантажує його.
4. Передзавантаження в продакшн-середовищі (Eager Loading in Production):
- У продакшн-режимі Rails використовує
Rails.application.eager_load!
для завантаження всіх файлів з шляхів автозавантаження під час запуску, щоб переконатися, що всі константи визначені.
Кращі практики для Zeitwerk
- Дотримуйтесь конвенцій іменування (Follow Naming Conventions):
- Переконайтесь, що імена класів/модулів відповідають шляхам файлів.
2. Уникайте кругових залежностей (Avoid Circular Dependencies):
- Уникайте ручного виклику
require
файлів; нехай Zeitwerk самостійно керує завантаженням.
3. Логічно організовуйте простори імен (Namespace Code Properly):
- Використовуйте послідовні та логічні простори імен для організації файлів.
4. Обробляйте крайні випадки (Handle Edge Cases):
-
Якщо потрібна спеціальна поведінка, можна використовувати
require_dependency
для конкретних файлів або налаштувати інфлектор Zeitwerk.
Уникайте застарілого автозавантаження (Avoid Legacy Autoloading): -
Rails відмовився від старого автозавантажувача
classic
. Використовуйте Zeitwerk для забезпечення сумісності в майбутньому.
6. Користувацька інфлекція (Custom Inflection):
- Якщо ви маєте незвичайні імена (наприклад, абревіатури або спеціальні випадки), можна налаштувати інфлектор Zeitwerk за допомогою
Rails.autoloaders.main.inflector
.
Налагодження проблем з автозавантаженням (Debugging Autoloading Issues)
Якщо виникають проблеми з автозавантаженням (наприклад, відсутні константи):
- Виконайте команду
bin/rails zeitwerk:check
, щоб перевірити, чи може Zeitwerk правильно завантажити всі файли. - Перевірте імена файлів та їх розташування, щоб переконатися, що вони відповідають конвенціям.
- Використовуйте
Rails.autoloaders.log!
для налагодження шляхів автозавантаження та завантаження файлів.
Перекладено з: How does Rails handle autoloading in modern versions using Zeitwerk