В данной статье я не буду вдаваться в подробности работы 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.