IoC & DI в Ruby (Inversion of Control & Dependency Injection)

185 views
Skip to first unread message

alexey.petrushin

unread,
Aug 15, 2011, 5:40:39 PM8/15/11
to RubyOnRails to russian
Хотел бы немного обсудить такую заброшенную концепцию как инверсия
управления.

На эту тему даже есть несколько презентаций, Джим Вейрих, еще кто-то -
создатель IoC Needle. Суть вкратце - они попробовали, у них получилось
хуже чем без и сделали вывод что IoC - неприменим для Ruby.

Мне кажется что то что их понимание того, что такое IoC / DI несколько
не полное (или может я что-то не так понимаю).

Восновном, все аргументы сводятся к тому что поскольку в руби и так
есть метапрограмминг то IoC не нужен. Подозреваю, что это происходит
из-за того что IoC пошли из мира Java и поскольку там нет
метапрограмминга, то байткод-манипуляция которую выполняет IoC имеет
огромное значение.
И, по моему из-за этого у многих создалось впечатление что байткод-
манипуляции и метапрограмминг - это и есть то чем должен занимаеться
IoC. Но это не так, это вообще не имеет никакого отношения к IoC, это
просто конкретная реализация этой концепции в Java.

При этом совершенно игнорируются то для чего IoC собственно и
создавался - разрешение зависимостей, автоматический поиск, загрузка,
конфигурирование и сборка.

Что самое смешное - предполагается использование IoC совместно с
'require' (никому не кажется это странным?) -особенно если учесть что
основное назначение IoC - как раз и есть - избавится от всяческих
'require' и прочих явных управлений зависимостями.

Вобшем, чуть больше ем полугода назад представился случай использовать
IoC для решения одной конкретной задачи, и по моему субьективному
мнению - использование IoC сильно ее упростило, вот этот IoC -
https://github.com/alexeypetrushin/micon

Там 2 конкретных примера - первый - краткая демонстрация что это
вообще такое и как он работает.
Первый пример - хороший пример как сделать Hello World с
использованием IoC, но при этом он также и отличный пример неверного и
неэффективного (в моем понимании) применения IoC.
Именно такое использование демонстрируется в вышеозначенных
презентациях и на его основании заключается неэффективность IoC
вообще.

Самое интересное во 2м примере, это тот-же первый пример, но
переделанный так как и должен работать (в моем понимании) IoC (он там
работает впаре с автоматическим загрузчиком классов). Там нет :require
и явных конфигов - все ищется, загружается, конфигурируется и
собирается автоматически.

Особенно заметно преимущество IoC, когда так-же автоматически, без
require, MyApp.config[:option_a] и прочего собирается приложение из
десятков компонентов разбросанных по где-то 8-11 гемам.

Вобщем, у меня ощущение - то-ли IoC незаслуженно забыты, я чего-то не
понимаю, было-бы интересно узнать что вы думаете.

P.S.
еще чуть подробнее про IoC http://ruby-lang.info/blog-ru/vy-niedootsienivaietie-moshch-ioc-u3l
а это собственно само приложение на его базе
http://ruby-lang.info/blog-ru/rad-vieb-frieimvork-po3

Max Lapshin

unread,
Aug 15, 2011, 5:55:59 PM8/15/11
to ror...@googlegroups.com
Я гляжу на это и видится мне такая проблема, общая вообще для
архитектуры приложений, но особо болезненно проявляющаяся в том, что я
увидел.

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

Можно даже надеяться, что когда-нибудь за время жизни приложения у
тебя будет больше одной реализации одного интерфейса. Ха-ха!

Вот тут мы подходим к очень болезненному моменту. Повторного
использования кода — полно. Библиотеки, которые действительно массово
используются есть на всех языках программирования. А вот обобщения API
между разными кусками кода объективно мало.

Но я считаю, что проблема спускания в библиотеку ссылки на какое-то
API — практически нерешаемая задача. Если и решаемая, то по счастливой
случайности и лишь до того момента, когда потребуется протащить
дополнительные модули, потому что потребовалась новая
функциональность.

Т.е. в реалии получается, что любой уродливый Java проект на половину
забит объявлениями интерфейсов, у которых никогда не будет больше
одной реализации. Более менее хоть что-то хоть как-то получилось с
логгерами (хотя всё равно половина проектов имеют свои логгеры с
обертками над обертками над логгерами). Как грустный пример — никаких
других примеров для аспектного программирования кроме логгеров обычно
не приводят.


Давай теперь насчёт твоего кода.
Удобно ли когда в любом месте есть logger под рукой? Это не просто
удобно, это очень важно. В ffmpeg например даже запрещено пользоваться
функциями вида puts, надо пользоваться логгером.

Удобно ли пользоваться micon.router. ? Извини, нет, особенно учитывая
что никакого другого роутера не будет. Вот не будет его и всё. А если
чем-то не устраивает текущий, то руби — не джава. Можно взять и
поправить безболезненным патчем в config/initializers и следующий
программист будет знать, куда посмотреть на предмет всяких хаков,
которые мешают обновлению рельс.

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

Что до меня, то has_many :clients выглядит куда как приятнее, чем
micon.register :client, :scope => :'manager.clients' или как там это
должно быть.

Илья Плотников

unread,
Aug 15, 2011, 5:58:53 PM8/15/11
to ror...@googlegroups.com
Как говорится если у вас есть проблема и вы решили решить ее с помощью
Java, то у вас появится еще AbstractProblem и FactoryProblem.
--
Всегда Ваш, Илья Плотников

Vladimir Chernyshev

unread,
Aug 15, 2011, 6:36:31 PM8/15/11
to ror...@googlegroups.com
IoC как концепция, по-моему, встроен в Ruby на уровне синтаксиса -
блоки и yield. Мы в какой-то метод инжектируем произвольный блок, о
котором метод ничего не знает, но его вызывает. Есть сложности с
нюансами типа нескольких зависимостей или возврата результатов, но,
имхо, блоки это чистой воды IoC.

16 августа 2011 г. 1:40 пользователь alexey.petrushin
<alexey.p...@gmail.com> написал:

> --
> --
> Данное сообщение отправлено Вам, так как Вы являетесь подписчиком группы "RubyOnRails to russian" на группах Google.
> FAQ группы находится по адресу: http://ru.wikibooks.org/wiki/RubyFAQ
>
>  Для того, чтобы отправить сообщение в эту группу, пошлите его по адресу
> ror...@googlegroups.com
>  Чтобы отменить подписку на эту группу, отправьте сообщение по адресу: ror2ru-un...@googlegroups.com
>  Дополнительные варианты находятся на странице группы http://groups.google.com/group/ror2ru?hl=ru

Message has been deleted

alexey.petrushin

unread,
Aug 15, 2011, 7:56:06 PM8/15/11
to RubyOnRails to russian
> Удобно ли пользоваться micon.router. ? Извини, нет

Хм, это был как раз пример нестандартного доступа, обычно
используется
вот так:

class App
inject router: :router
def do
router.do_something
end
end

Если так тоже неудобно, то хотелось бы пример - как удобно.


> Т.е. в реалии получается, что любой уродливый Java проект на половину
> забит объявлениями интерфейсов, у которых никогда не будет больше
> одной реализации.

...

> Удобно ли пользоваться micon.router. ? Извини, нет, особенно учитывая
> что никакого другого роутера не будет. Вот не будет его и всё. А если

> чем-то не устраивает текущий, то руби -- не джава. Можно взять и


> поправить безболезненным патчем в config/initializers

1. У меня впечатление что ты концентрирушся на возможности быстрой
смены компонентов, это да, одно из преимуществ IoC, но для меня лично
это второстепенно, и не важно, как ты верно отметил - руби и так
позволяет легко это делать использую метапрограммиг и duck-typing.
Гораздо важнее другое - управление зависимостями.

Вот пример реального роутера https://github.com/alexeypetrushin/rad_core/blob/master/lib/components/router.rb
(там всего пара строчек), там видно что у роутера стоит 2 зависимости,
это позволяет легко контролировать зависимости и делать ленивую
загрузку приложения.

Можно возразить "require делает то-же самое" - нет, когда я ставлю в
зависимость компонент (у этого роутера в дереве зависимостей
есть :environment), то это означает не просто
загрузить класс Environment, а загрузить и сконфигурировать используя
конфиг продакшена.
Например компонент :models (не отдельная модель, а сам фреймворк
моделей) во время инициализации читает конфигурацию базы и выполняет
подключение.

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

Т.е. получается просто отличное инкапсулирование и независимость -
просто обьяви какие компоненты тебе нужны - и они сами автоматически
появятся в нужное время.

2. Чуть подробней про конфиги, там еще есть такой файл
https://github.com/alexeypetrushin/rad_core/blob/master/lib/components/router.yml
И если мне вздумается перегрузить эти настройки - достаточно просто
поместить с таким-же названием и нужной строчкой в продакшен-пути -
они будут смержены.
Т.е. любая из настроек любого из компонентов приложения может быть
легко перегружена таким способом. И не нужно читать документацию и
помнить как именно настраивается тот или иной компонент - все они
настраиваются одинаково.
Там кстати есть еще одна проблема которую сразу не видно, и которая
собственно и вынудила меня разрезать один конфиг на множество -
компоненты инициализируются в определенном порядке, и когда весь
конфиг в одном файле - то очень сложно мержить и перегружать
настройки. А так все тривиально.

> Что до меня, то has_many :clients выглядит куда как приятнее, чем
> micon.register :client, :scope => :'manager.clients' или как там это
> должно быть.

Хм, это вообще никак не связано, совершенно из другой области.
Описание связей между моделями никак не относится к IoC.
Что именно навело на такую мысль, что-то в описаниии примера? Если
так, что именно? (я тогда поправлю описание чтобы было более понятно).

> Как говорится если у вас есть проблема и вы решили решить ее с помощью Java,
> то у вас появится еще AbstractProblem и FactoryProblem.

Я привел пример Java для того чтобы было понятно откуда на мой взгляд
идет предвзятое отношение и своеобразное восприятие IoC.
И наоборот имел ввиду что нельзя брать и использовать техники Java
напрямую, потому что они не подходят к Ruby.
Добавляется всего 3 понятия:
- register(component)
- inject(component) / micon.component
- путь к папке конфигов и компонентов 'lib/components'
- activate(scope) не в счет, он черезвычайно редко используется, и
только в очень низкоуровневой логике.

Что имеется ввиду конкретно в данном случае? Где фэктори, сложности, и
т.д.?

Кстати, забыл упомянуть - получается6 что расходов и сложностей
собственно и нет, вы почти не несете никаких дополнительных расходов
(за исключением необходимости помнить эти 3 метода и помещать
обьявления компонентов в папку lib/components)

П.С.
Хм завтра ради интереса сделаю второй пример без IoC и посчитаю число
символов.

alexey.petrushin

unread,
Aug 16, 2011, 11:18:17 AM8/16/11
to RubyOnRails to russian
> IoC как концепция, по-моему, встроен в Ruby на уровне синтаксиса -
> блоки и yield. Мы в какой-то метод инжектируем произвольный блок, о
> котором метод ничего не знает, но его вызывает. Есть сложности с
> нюансами типа нескольких зависимостей или возврата результатов, но,
> имхо, блоки это чистой воды IoC.

Ок, наверно не нужно было использовать термин IoC, он лишком много
всего обозначает.

Правильней будет назвать это Dependency Injection, или другими
словами: Micon - это компонент который автоматически разбирает
зависимости, собирает и конфигурирует приложение.
Или, более подробно, он позволяет сделать следущее:

- разделить приложение на части которые ничего не знают друг о друге
кроме имени и нескольких публичных методов
- полностью избавится от конфигов в коде
- просто перегружать любые значения конфигурации любых компонентов в
различных вариантах сборки и енвайронментах
- полностью избавится от 'require' и вообще какого-либо упоминания
зависимостей в виде путей и файлов
- автоматически управлять жизненным циклом группы связанных
компонентов (напр создавать и удалять request/params/session/
controller/view на каждый запрос)
- автоматически собирать компоненты для тестов и обеспечить изоляцию
между тестами (восстановение состояния после теста)
- за все это практически не нужно ничем платить (кроме запоминания 3х
методов и папки lib/components)

П.С.
Кстати, спасибо за отзывы, уже понял что то описание которое есть -
неверное: под IoC каждый понимает что-то свое и во вторых - IoC
отвечает на впорос "как делает", а место этого нужно дать ответ на
вопросы "зачем нужен/что делает".

pyromaniac -

unread,
Aug 16, 2011, 11:39:39 AM8/16/11
to ror...@googlegroups.com
IoC - в общем и целом, это концепция любого фреймворка, фактически одно из важнейших характерных отличий фреймворка от библиотеки. Поэтому рельсы и иже с ними - это IoC в чистом виде. Что же касается разбора зависимостей - этим в мире руби занимаются rubygems/bundler + autoload из активсуппорта. Которые, кстати, значительно проще, чем всякие многоэтажные конструкции.

16 августа 2011 г. 19:18 пользователь alexey.petrushin <alexey.p...@gmail.com> написал:

Max Lapshin

unread,
Aug 16, 2011, 11:51:13 AM8/16/11
to ror...@googlegroups.com
2011/8/16 alexey.petrushin <alexey.p...@gmail.com>:

> Правильней будет назвать это Dependency Injection, или другими
> словами: Micon - это компонент который автоматически разбирает
> зависимости,

Как можно автоматически сделать то, над чем приходится серьезно
подумать человеку?

>
> - разделить приложение на части которые ничего не знают друг о друге
> кроме имени и нескольких публичных методов

Не будет такого в реальной жизни. Зависимости проникают между всеми
слоями приложения.

> - полностью избавится от конфигов в коде

Зачем?

> - просто перегружать любые значения конфигурации любых компонентов в
> различных вариантах сборки и енвайронментах

Зачем?

> - полностью избавится от 'require' и вообще какого-либо упоминания
> зависимостей в виде путей и файлов

Зачем?

> - автоматически управлять жизненным циклом группы связанных
> компонентов (напр создавать и удалять request/params/session/
> controller/view на каждый запрос)

Уже сделано:

block do
Request.new
end


> - автоматически собирать компоненты для тестов и обеспечить изоляцию
> между тестами (восстановение состояния после теста)

Уже сделано. См test/unit или rspec

> - за все это практически не нужно ничем платить (кроме запоминания 3х
> методов и папки lib/components)

и более непонятного связывания компонент.

Откуда такая уверенность, что динамическое связывание компонент — это хорошо?
Ведь ребенку понятно, что код вида object->setWidth() более понятен,
чем object->invoke("setWidth", ...), потому как
это постоянно заканчивается object->invoke(method, args) и становится
совершенно непонятно, куда дальше
уйдет управление.

alexey.petrushin

unread,
Aug 16, 2011, 3:32:11 PM8/16/11
to RubyOnRails to russian
> Как можно автоматически сделать то, над чем приходится серьезно подумать человеку?
Так-же как AcriveRecord делает тривиальными вполне себе сложные
запросы. Он делает простыми запросы на которые приходится 90% всех
случаев использования и прямой доступ к драйверу если нужно что-то
специфичное.
Так-же и тут, большая часть всех зависимостей сводится к таким вещам
как: загрузить зависимости, загрузить код, загрузить конфиг, собрать и
связать с другим приложением. Micon разрешает такие случаи
автоматически.

> > полностью избавится от конфигов в коде
> Зачем?

> > - полностью избавится от 'require' и вообще какого-либо упоминания
> > зависимостей в виде путей и файлов
> Зачем?

Зачем делают рефакторинг и удаление ненужного и лишнего кода? Чтобы
упростить систему.

> > просто перегружать любые значения конфигурации любых компонентов в различных вариантах сборки и енвайронментах
> Зачем?

чтобы приложение можно было строить в виде многократно используемых
модулей, которые просто настраивать в различном окружении: blog/forum/
cms
а не в виде одной папки app/controllers/* где находится много-много
десятков контроллеров.

> > - разделить приложение на части которые ничего не знают друг о друге
> > кроме имени и нескольких публичных методов
> Не будет такого в реальной жизни. Зависимости проникают между всеми
> слоями приложения.

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

> > - автоматически собирать компоненты для тестов и обеспечить изоляцию
> > между тестами (восстановение состояния после теста)
> Уже сделано. См test/unit или rspec

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

> и более непонятного связывания компонент.

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


> Откуда такая уверенность, что динамическое связывание компонент -- это хорошо?


> Ведь ребенку понятно, что код вида object->setWidth() более понятен,
> чем object->invoke("setWidth", ...), потому как
> это постоянно заканчивается object->invoke(method, args) и становится
> совершенно непонятно, куда дальше
> уйдет управление.

это как посмотреть, когда этот object->invoke('setWidth', ...) всего в
одном экземпляре, а конструкций типа object->setXxx() сотни
разбросанных по всей системе - то что это спорный вопрос что проще.

П.С.
кстати, если вам что-то показалось непонятным или странным в
документации - дайте знать пожалуйста,

Max Lapshin

unread,
Aug 16, 2011, 3:51:23 PM8/16/11
to ror...@googlegroups.com
2011/8/16 alexey.petrushin <alexey.p...@gmail.com>:

> Так-же как AcriveRecord делает тривиальными вполне себе сложные
> запросы. Он делает простыми запросы на которые приходится 90% всех
> случаев использования и прямой доступ к драйверу если нужно что-то
> специфичное.

ActiveRecord делает тривиальными тривиальные запросы, которые в силу
говорливого SQL-я выглядят достаточно громоздко, хотя от этого не
перестают быть тривиальными.

Если запрос на SQL действительно сложный, то ActiveRecord не спасает.
Причём тут IoC я не понимаю.

> Так-же и тут, большая часть всех зависимостей сводится к таким вещам
> как: загрузить зависимости, загрузить код, загрузить конфиг, собрать и
> связать с другим приложением. Micon разрешает такие случаи
> автоматически.

Вот в чём проблема то в рельсах загрузить код? Даже require писать уже
не надо: автолоадер стал достаточно предсказуемым и очень удобным.
Загрузить конфиг проще простого: Config = YAML.load(Rails.root +
"/config/app-" + Rails.env + ".yml")
Зачем мне тут дополнительный уровень косвенности?

> Зачем делают рефакторинг и удаление ненужного и лишнего кода? Чтобы
> упростить систему.
>

Покажи код, который ты считаешь сложным и как ты его упростишь? Я не
увидел пока этого в примерах.


> Скажем так, этого почти не бывает в рельсах, точнее я не видел,

Во-первых «я не видел» — это хорошая поправка. На деле возникают проблемы.

Вот делали мы биллинг. Думаешь это очень просто так задизайнить
систему приёма платежей так, что бы её можно было выдрать из одного
приложения и вставить в другое? Хрен там. Я вообще не уверен в том,
что это возможно сделать и причина тому в том, что действительно
разнообразная бизнес-логика делает механизм обобщенного наследования
кода неприемлемо сложным.

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


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

Куда идти то? Написан какой-то абстрактный вызов какого-то модуля,
который неизвестно где определится.
Куда мне смотреть следующей строчкой?

> это как посмотреть, когда этот object->invoke('setWidth', ...) всего в
> одном экземпляре, а конструкций типа object->setXxx() сотни
> разбросанных по всей системе - то что это спорный вопрос что проще.

Явные вызовы легче отследить.


>
> П.С.
> кстати, если вам что-то показалось непонятным или странным в
> документации - дайте знать пожалуйста,
>

Непонятно, какая проблема решается.

alexey.petrushin

unread,
Aug 16, 2011, 4:56:05 PM8/16/11
to RubyOnRails to russian
> Загрузить конфиг проще простого: Config = YAML.load(Rails.root +
> "/config/app-" + Rails.env + ".yml")
> Зачем мне тут дополнительный уровень косвенности?
Там немного другой подход, конфиг можно делать на каждый компонент,
это позволяет легко их настраивать.
И поэтому удобно когда это делается автоматически а не вручную каждый
раз.

> Покажи код, который ты считаешь сложным и как ты его упростишь? Я не
> увидел пока этого в примерах.

Хм, там вроде есть (во вчерашних примерах не было, но седня в новом я
добавил это), в случае без Micon'а нужен такой код:

# reading application config
require 'yaml'
Ultima.config = YAML.load_file "#{dir}/config/config.yml"

# initializing router
require 'router'
router = Router.new
router.url_root = Ultima.config['url_root']
Ultima.router = router

# loading request and controller
require 'request'
require 'controller'

# Assemblilng Application
require 'pages_controller'

А во втором примере, с Micon - все это делается автоматически.
По настоящему сложный пример привести сложно потому что это-же всетаки
пример а не полноценное приложение.

> Непонятно, какая проблема решается.
Я лично использую его в качестве склета для небольшлго фреймворка -
клона рельсов ( http://ruby-lang.info как пример простого сайта).
Одной из задач было - сделать возможным разделение как приложения так
и самого фреймворка на части, и пытаясь сделать это я заметил что
многократно повторяю один и тот-же сценарий связанный со сборкой
компонентов. Я выделил его в отдельный фреймворк - это собственно
Micon и есть.

Но наверно да, такой низкоуровневый компонент, без конкретного примера
- не особо понятно зачем он нужен.

On 16 авг, 23:51, Max Lapshin <max.laps...@gmail.com> wrote:
> 2011/8/16 alexey.petrushin <alexey.petrus...@gmail.com>:


>
> > Так-же как AcriveRecord делает тривиальными вполне себе сложные
> > запросы. Он делает простыми запросы на которые приходится 90% всех
> > случаев использования и прямой доступ к драйверу если нужно что-то
> > специфичное.
>
> ActiveRecord делает тривиальными тривиальные запросы, которые в силу
> говорливого SQL-я выглядят достаточно громоздко, хотя от этого не
> перестают быть тривиальными.
>
> Если запрос на SQL действительно сложный, то ActiveRecord не спасает.
> Причём тут IoC я не понимаю.
>
> > Так-же и тут, большая часть всех зависимостей сводится к таким вещам
> > как: загрузить зависимости, загрузить код, загрузить конфиг, собрать и
> > связать с другим приложением. Micon разрешает такие случаи
> > автоматически.
>
> Вот в чём проблема то в рельсах загрузить код? Даже require писать уже
> не надо: автолоадер стал достаточно предсказуемым и очень удобным.
> Загрузить конфиг проще простого: Config = YAML.load(Rails.root +
> "/config/app-" + Rails.env + ".yml")
> Зачем мне тут дополнительный уровень косвенности?
>
> > Зачем делают рефакторинг и удаление ненужного и лишнего кода? Чтобы
> > упростить систему.
>
> Покажи код, который ты считаешь сложным и как ты его упростишь? Я не
> увидел пока этого в примерах.
>
> > Скажем так, этого почти не бывает в рельсах, точнее я не видел,
>

> Во-первых <<я не видел>> -- это хорошая поправка. На деле возникают проблемы.

Oleh Khomey

unread,
Aug 16, 2011, 6:53:40 PM8/16/11
to ror...@googlegroups.com


Regards,
  Oleh Khomey


2011/8/16 alexey.petrushin <alexey.p...@gmail.com>

Мохнатый

unread,
Aug 17, 2011, 5:02:01 AM8/17/11
to RubyOnRails to russian
Для всех дополнительных классов достаточно один раз написать
initializer в одну строчку и все они будут подгружаться и не нужно
будет об этом заботиться при добавлении нового класса. А вызовы
require не так уж и часто встречаются и не сложно написать их пару
раз, чем грузить в приложение какого-то монстра. Это мое ИМХО.

On Aug 17, 3:53 am, Oleh Khomey <varyf...@gmail.com> wrote:
> Regards,
>   Oleh Khomey
>

> 2011/8/16 alexey.petrushin <alexey.petrus...@gmail.com>

Reply all
Reply to author
Forward
0 new messages