Как на самом деле работают RVM и rbenv?
меня интересует, как RVM и rbenv на самом деле работают.
очевидно, что они меняются между различными версиями Ruby и gemsets, но как это достигается? Я предполагал, что они просто обновляют символические ссылки, но, углубившись в код (и я должен признать, что мои знания о Bash поверхностны), они, похоже, делают больше, чем это.
5 ответов:
краткое объяснение: rbenv работает, подключаясь к вашей среде
PATH. Концепция проста, но дьявол в деталях; полный совок ниже.во-первых, rbenv создает прокладки для всех команд (
ruby,irb,rake,gemи так далее) во всех установленных версиях Ruby. Этот процесс называется украшения. Каждый раз, когда вы устанавливаете новую версию Ruby или устанавливаете gem, который предоставляет команду, запуститеrbenv rehashto убедитесь, что все новые команды перекрываются.эти прокладки живут в одной директории (
~/.rbenv/shimsпо умолчанию). Чтобы использовать rbenv, вам нужно только добавить каталог shims в переднюю часть вашегоPATH:export PATH="$HOME/.rbenv/shims:$PATH"тогда в любое время вы запускаете
rubyиз командной строки, или запустить скрипт, который shebang читает#!/usr/bin/env ruby, ваша операционная система найдет~/.rbenv/shims/rubyсначала запустите его вместо любого другогоrubyисполняемый файл, который вы могли установить.каждая прокладка крошечная Bash скрипт, который в свою очередь работает
rbenv exec. Так что с rbenv на вашем пути,irbэквивалентноrbenv exec irbиruby -e "puts 42"эквивалентноrbenv exec ruby -e "puts 42".The
rbenv execкоманда выясняет, какую версию Ruby вы хотите использовать, а затем запускает соответствующую команду для этой версии. Вот как:
- если
RBENV_VERSIONустановлена переменная окружения, ее значение определяет версию Ruby для использования.- если текущий рабочий каталог имеет
.rbenv-versionфайл, его содержимое используется для установкиRBENV_VERSIONпеременные среды.- если нет
.rbenv-versionфайл в текущем каталоге, rbenv ищет каждый родительский каталог для.rbenv-versionфайл, пока он не попадет в корень вашей файловой системы. Если он найден, его содержимое используется для установкиRBENV_VERSIONпеременные среды.- если
RBENV_VERSIONвсе еще не установлен, rbenv пытается установить его, используя содержимое .- если версия нигде не указана, rbenv предполагает, что вы хотите использовать "системный" Ruby-т. е. любую версию, которая была бы запущена, если бы rbenv не был на вашем пути.
(вы можете установить версию Ruby для конкретного проекта с помощью
rbenv localкоманда, которая создает.rbenv-versionфайл в текущем каталоге. Точно так же, изменить .)вооружившись
RBENV_VERSIONпеременная окружения, rbenv добавляет~/.rbenv/versions/$RBENV_VERSION/binвпередиPATH, затем выполняет команду и аргументы, переданныеrbenv exec. Вуаля!для тщательного изучения того, что именно происходит под капотом, попробуйте установить
RBENV_DEBUG=1и запуск команды Ruby. Каждая команда Bash, которую запускает rbenv, будет записана на ваш терминал.
теперь rbenv просто занимается переключением версий, но процветающая экосистема плагинов поможет вам сделать все от установка Ruby до настройки среды,управление "gemsets" и даже автоматизация
bundle exec.я не совсем уверен, что поддержка IRC имеет отношение к переключению версий Ruby, а rbenv разработан так, чтобы быть простым и понятным, чтобы не требовать поддержки. Но если вам когда-нибудь понадобится помощь, проблема tracker и Twitter находятся всего в нескольких кликах.
раскрытие информации: я являюсь автором rbenv, ruby-build и rbenv-vars.
Я написал подробную статью: http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/
основное различие заключается в том, где среда оболочки изменяется:
- RVM: это изменилось, когда вы меняете Ruby.
- rbenv: он изменяется при запуске исполняемого файла Ruby/gem.
кроме того, дело в RVM, он охватывает гораздо больше, чем просто управление рубинами, он имеет намного больше, чем любой другой инструмент (есть другие, кроме RVM и rbenv:https://twitter.com/#! / mpapis / статус/171714447910502401)
Не забывайте о мгновенной поддержке, которую вы получаете на IRC в канале "#rvm " на серверах Freenode.
Итак, чтобы суммировать отличные ответы выше, основное практическое различие между RVM и rbenv заключается в том, когда выбрана версия Ruby.
rbenv:
rbenv добавляет прокладку в начало вашего пути, команду с тем же именем, что и Ruby. При вводе
rubyв командной строке вместо этого запускается прокладка (потому что она также называется "ruby" и занимает первое место в пути). Прокладка ищет переменную окружения или.rbenv_versionфайл, чтобы сказать ему, что версия Ruby для делегирования.RVM:
RVM позволяет установить версию Ruby непосредственно по телефону
rvm use. Кроме того, он также переопределяетcdкомандная система. Когда тыcdв папку, содержащую.rvmrcфайл, код внутри.rvmrcфайл выполнен. Это может быть использовано для установки версии Ruby, или что-нибудь еще вам нравится.другие отличия:
есть конечно и другие различия. RVM имеет gemsets из коробки, в то время как rbenv требует немного больше взлома (но не так много). Оба являются функциональными решениями проблемы.
rvm system env > before rvm jruby # or whatever env > after diff after beforeдает вам примерно:
< GEM_HOME=$HOME/.gem/ruby/1.9.1 --- > GEM_HOME=$HOME/.rvm/gems/jruby-1.6.6 < GEM_PATH=$HOME/.gem/ruby/1.9.1 --- > GEM_PATH=$HOME/.rvm/gems/jruby-1.6.6:$HOME/.rvm/gems/jruby-1.6.6@global *bunch of rvm_* > MY_RUBY_HOME=$HOME/.rvm/rubies/jruby-1.6.6 > RUBY_VERSION=jruby-1.6.6 > IRBRC=$HOME/.rvm/rubies/jruby-1.6.6/.irbrcи добавляет:
$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/jruby-1.6.6@global/binдо
$PATH
основное отличие, кажется,когда и как Рубин перешел. Рубин переключается:
- для RVM вручную (использование rvm) или автоматически при смене каталогов
- для rbenv автоматически при каждом выполнении команды ruby
RVM полагается на модифицированный
cdкоманда и ручной выбор Ruby byrvm use. rbenv использует обертки или "прокладки" для всех основных команд ruby в качестве механизма по умолчанию для выбора ruby. РВМ создает обертки для основных инструментов командной строки, таких как gem, rake, ruby. Они используются, например, в CronJobs ( см. http://rvm.io/integration/cron/), но они не являются механизмом по умолчанию для переключения версии Ruby.
Comments