Как стать автором
Обновить

Почему всё-таки стоит пользоваться RVM, а не rbenv+ruby-build

Время на прочтение 5 мин
Количество просмотров 6.8K
Автор оригинала: Michał Papis
В противовес к этой статье. Мне удалось немного покопаться с rbenv, наткнуться на несколько граблей, и решить копнуть поглубже. И очень ко времени попалась на глаза вот эта статья, перевод которой я на ваше обозрение и предоставляю.

На сегодняшний день уже не осталось тех, кто не слышал о RVM или rbenv. Как содействовавший разработке RVM, я подумал, что стоит выяснить, что именно делает rbenv. Чтение исходного кода дало мне представление об rbenv, и, к сожалению, я не нашёл никакого нового трюка для работы в оболочке командной строки. Тем не менее, я понимаю, как обе этих утилиты работают, и могу найти разницу в их работе. Обе утилиты предоставляют возможность переключать активную версию Ruby.

Основная разница состоит в способе переключения Ruby.

Для RVM всё происходит в момент смены текущей директории, только один раз, и в тот самый момент все исполняемые файлы и gem'ы Ruby становятся доступны. Можно также запустить эту процедуру вручную.
Для rbenv, все исполняемые файлы Ruby и gem всегда доступны в оболочке, но загрузят нужный код только в подходящем контексте, то есть вычисление происходит каждый раз при запуске исполняемого файла.
Глубже в детали: RVM потратит 60мс на каждый запуск cd, что составит секунду времени на 16 смен директории. Во время смены директории, RVM установит все переменные окружения таким образом, чтобы те указывали на текущую версию Ruby и текущий gemset, позволяя отделить их от других версий Ruby, gem'ов и исполняемых файлов. Вы не сможете запустить исполняемый файл, который относится к gem'у другого проекта.

Для rbenv смена директоий не несёт временных затрат, то есть в вопросе смены директорий rbenv быстрее. После установки новых gem'ов потребуется 60мс для запуска rbenv rehash. Смена текущей версии Ruby или смена директории не меняет окружение, кроме переменной RBENV_VERSION, но при этом каждый раз при запуске исполняемого файла будет затрачено 50мс на вычисление обёрткой того, какой же именно файл нужно исполнить для текущей версии Ruby и gemset'а.

Чтобы подробнее объяснить, что же именно делает rbenv, вот цитата моего сообщения на reddit:
Есть один большой недостаток в способе с обёртками — все исполняемые файлы и бинарные файлы Ruby и gem'ов всегда доступны в оболочке, что не всегда удобно.
Если, например, HAML, установлен для одной версии Ruby, его исполняемый файл будет доступен всем остальным версиям.
Способ с обёртками работает вопреки системе — строить абстракцию, не уважая принципы работы UNIX, такие как поиск по PATH, это одурение системы (и вас).
Невозможно запустить обёртку/Ruby без rbenv, который принципиально необходим, чтобы окружение работало так, как ожидается. RVM же, наоборот, по умолчанию строит окружение так, что система понимает, как должна работать без вмешательства RVM.


Окружение готово к запуске исполненяемых файлов в обоих случаях, но слегка по разному для рассматриваемых утилит:
— есть разница в моменте загрузки окружения. Для RVM можно запустить 'rvm info', для rbenv запускать нечего; (прим перев. на самом деле можно запустить 'rbenv version')
— для RVM только выбранные и необходимые Ruby/gem исполняемые файлы будут доступны в оболочке. Для rbenv все исполняемые файлы будут доступны, только некоторые из них не будут ничего делать при запуске; нет возможности проверить, доступен ли исполняемый файл в системе, так как проверка будет наталкиваться на обёртку и сообщать о её существовании;
— тем, кого беспокоит время загрузки и исполнения файлов, не заметят особой разницы, её можно лишь измерить. Задержки менее 300мс не заметны для пользователя оболочки (прим. перев. есть мнение, что 150мс, но обе утилиты укладываются и в этот диапазон тоже).

Автор rbenv, Сэм Стивенсон, приводит различия между утилитами, критикуя RVM, давайте рассмотрим их:
1. Необходимость загрузки в оболочку. Напротив, способ rbenv с обёртками работает, добавляя папку в ваш PATH. RVM также нет необходимости загружать в оболочку. Он позволяет работать лишь загружая файл окружения, что происходит только раз и позволяет единожды и быстро проинициализировать текущую версию Ruby и gemset.

2. Перегружает команды оболочки, такие как cd. Это опасно и может привести к ошибкам. Перегрузка cd опциональна. Я искал суммарно почти 8 часов за последний месяц, чтобы найти проект, который перегружает cd — и что вы думаете? Не нашёл. В любом случае, RVM предоставляет возможность смотреть на тот код, который будет исполнен при запуске cd до момента его исполнения и выбирать, доверять ему или нет.

3. Имеет конфигурационный файл. Нечего конфигурировать, кроме версии Ruby, которую вы хотитие использовать. rbenv в настоящий момент может выставлять до 4х переменных оболочки, которые влияют на запущенные процессы, и нет конфгурационного файла для их настройки, все они должны быть настроены в rc файлах, по одному на каждый тип оболочки из тех, что вы используетет. (прим перев. не понимаю, о каких четырёх переменных идёт речь, зачем тут нужен конфигурационный файл, и как смена версии Ruby в одной из сессий может повлиять на запущенные процессы, и почему автор не знает, что для всех оболочек можно использовать один общий файл, но мнение есть мнение).

4. Устанавливает Ruby. Вы можете установить Ruby самостоятельно, или использовать ruby-build для автоматизации процесса. За своё долгое существование RVM собрал немалый багаж знаний о том, как устанавливать и управлять версиями Ruby, включая патчи для различных окружений.

5. Управляет gemset'ами. Bundler — лучший способ управлять зависимостями приложения. Если проект ещё не использует Bundler, есть возможность установить плагин rbenv-gemset. Использование gemset'ов опционально, но рекомендовано, так как оно упрощает процесс разделения. Само существование плагина rbenv-gemset только подтверждает это. Даже могучий Bundler не всегда может разобраться в запутанных отношениях gem'ов. Ко всему прочему, не всегда удобно запускать Rake вызывая 'bundle exec rake'.

6. Требует внесения в библиотеки Ruby для совместимости. Простота rbenv позволяет лишь держать его в PATH, больше ничего не требуется. RVM не требует изменений в gem'ах и библиотеках.



В ответ Сэму Стивенсону я дам несколько контраргументов против использования rbenv:
1. Выполнение исполненяемого файла на 50мс медленнее, чем для RVM, так что если вы используете много вызовов Ruby исполняемых файлов, можете получить выигрыш с RVM.
2. Выполнение исполненяемого файла не требует, чтобы нужный исполняемый файл был доступен, оно втихую сорвётся без единого предупреждения, что файл не доступен.
3. Невозможно проверить наличие того или иного исполняемого файла в системе, требуются дополнительные ухищрения. С RVM достаточно настроить окружение — и всё работает в соглашении с идеологией UNIX. С rbenv же окружение обмануто обёртками.

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

Часто упоминается сложность и размер RVM. rbenv — довольно новый проект, и он пока относительно мал и его код относительно прост. С ростом количества возможностей растёт и сложность проекта. Мы с нетерпением ждём, как rbenv вырастет в замечательный продукт, сохраняя простоту, чтобы оба проекта могли заимствовать друг у друга лучшее.

Есть ещё одна вещь, которая стала доступна пользователям OSX, это официальный GUI для RVM, Jewelery Box, спрос на которую оказался велик.

Подводя итог хочется заметить, что мы в курсе, что RVM вырос, и некоторый рефакторинг бы не помешал тем, кто пытается начать участвовать в его развитии, а также сделать исходный код более читаемым и поддерживаемым. Мы проектируем RVM2 как расширение SM, ещё одного замечательного инструмента от того же автора, Уэйна Сегуина, на который стоит обязательно посмотреть, а чтобы описать который понадобится не одна статья.
Мы слышим наших пользователей громко и отчётливо, и у нас большие планы на будущее RVM.
Теги:
Хабы:
+24
Комментарии 20
Комментарии Комментарии 20

Публикации

Истории

Работа

Программист Ruby
15 вакансий
Ruby on Rails
17 вакансий

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн