Когда нужен RVM, а когда достаточно rbenv
В данной статье я не буду вдаваться в подробности работы RVM и rbenv. Информации по данным штуковинам хватает на просторах интернета. Здесь же я хочу попытаться раскрыть вопрос: когда стоит использовать rbenv, а когда нет?
Цель
Для этого давайте для начала разберемся для чего же создавался RVM, а для чего rbenv. Для этого достаточно взглянуть на возможности обоих систем.
Возможности rbenv
- Установка различных версий ruby
- Удаление их по отдельности
- Изменение версии ruby в системе
- Изменение версии ruby для конкретного проекта
- Установка гемов для текущей версии ruby в систему (точнее в путь установки текущей версии ruby)
Это все возможности
Возможности RVM
Так как возможностей очень много (все можно посмотреть на официальном сайте) то здесь я приведу основные.
- Установка различных версий ruby
- Удаление их по отдельности
- Установка гемсетов
- Удаление гемсетов
- Перекличение между версиями ruby в системе
- Перекличение между гемсетами в системе
- Создание конфигурации ruby или гемсета для конкретного проекта
На этом остановимся. Список будет в 2 раза больше из-за того, что RVM поддерживает не только манипуляции с ruby, но и с гемсетами.
Зачем нужны гемсеты?
Когда bundler’а не было на свете, все гемы, нужные для проекта, ставились в систему и смешивались с гемами, используемыми другим проектом. В итоге мы получали кашу с различными гемами различных версий, проект использовал гем не той версии при запуске и падал, а то еще хуже — заводился и работал не так как хотелось бы, либо вовсе гем не включался в проект по непонятным причинам. Альтернативным путем решения было конечно замараживать их в vendor/, но это решение не позволяло обновлять гемы (это нужно было делать вручную), да и проект весил в несколько раз больше. С появлением bundler появилась возможность ставить гемы необходимые для проекта куда угодно (для этого нужно передать в bundle install переменную --path), причем эти гемы никак не повлияют на работу другого проекта. В итоге мы получаем то, что делает за нас RVM — рабочую лошадку по управлению гемсетов, но для этого нам не нужен RVM!
В этом и кроется ответ на главный вопрос этого поста. В последнее время сложно найти проект, в котором не используется bundler. Если Вы используется bundler во всех проектах, использование RVM теряет смысл.
Как я использую rbenv
Допустим мы имеем два проекта A(rails 3, ruby 1.9.1) и B (rails 2, ruby 1.8.7), в системе установлен rbenv с этими версиями ruby. Мои действия:
- Захожу в путь проекта B
- Выполняю rbenv local 1.8.7. Это создаст файл .rbenv-version и теперь при нахождении в этой директории версия ruby будет устанавливаться из этого файла
- bundle install --path=vendor/bundle. Это заморозит гемы, описанные в Gemfile в путь ./vendor/bundle
- Делаю тоже самое с проектом A, устанавлявая версию 1.9.1
Это все. В итоге мы имеем 2 проекта с разными, не пересекающимися, наборами гемов для различным версий ruby. Если мы зайдем в проект A, у нас автоматически установится в оболочке ruby 1.9.1. При запуске сервера будет использоваться ruby 1.9.1 и набор гемов из vendor/bundle.
Огромный плюс в том, что мы можем без особых проблем анализировать исходный код гемов и изменять их, если это конечно необходимо. Я считаю, плюс в том, что исходный код всех гемов будет лежать в проекте, а не где-то там, очевиден и не требует подробного объяснения и разбора полетов.
Зачем тогда RVM?
Рационально использовать RVM получается только в одном случае: если в проектах не используется bundler.