Je suis intéressé par le fonctionnement réel de RVM et rbenv.
Évidemment, ils échangent entre différentes versions de Ruby et les ensembles de gemmes, mais comment cela est-il réalisé? J'avais supposé qu'ils mettaient simplement à jour des liens symboliques, mais après avoir fouillé dans le code (et je dois admettre ma connaissance de Bash est superficiel), ils semblent faire plus que cela.
Brève explication: rbenv fonctionne en se connectant au PATH
de votre environnement. Le concept est simple, mais le diable est dans les détails; scoop complet ci-dessous.
Tout d'abord, rbenv crée des cales pour toutes les commandes (Ruby
, irb
, rake
, gem
et ainsi de suite) sur toutes vos versions installées de Ruby. Ce processus est appelé rehashing . Chaque fois que vous installez une nouvelle version de Ruby ou installez une gemme qui fournit une commande, exécutez rbenv rehash
pour vous assurer que toutes les nouvelles commandes sont calées.
Ces cales vivent dans un seul répertoire (~/.rbenv/shims
par défaut). Pour utiliser rbenv, il vous suffit d'ajouter le répertoire shims au début de votre PATH
:
export PATH="$HOME/.rbenv/shims:$PATH"
Ensuite, chaque fois que vous exécutez Ruby
à partir de la ligne de commande ou exécutez un script dont Shebang lit #!/usr/bin/env Ruby
, votre système d'exploitation trouvera ~/.rbenv/shims/Ruby
d'abord et exécutez-le à la place de tout autre exécutable Ruby
que vous pourriez avoir installé.
Chaque shim est un petit script Bash qui à son tour exécute rbenv exec
. Donc, avec rbenv sur votre chemin, irb
est équivalent à rbenv exec irb
, et Ruby -e "puts 42"
est équivalent à rbenv exec Ruby -e "puts 42"
.
Le rbenv exec
commande détermine quelle version de Ruby vous souhaitez utiliser, puis exécute la commande correspondante pour cette version. Voici comment:
RBENV_VERSION
la variable d'environnement est définie, sa valeur détermine la version de Ruby à utiliser..rbenv-version
fichier, son contenu est utilisé pour définir le RBENV_VERSION
variable d'environnement..rbenv-version
dans le répertoire courant, rbenv recherche dans chaque répertoire parent un .rbenv-version
fichier jusqu'à ce qu'il atteigne la racine de votre système de fichiers. S'il en trouve un, son contenu est utilisé pour définir le RBENV_VERSION
variable d'environnement.RBENV_VERSION
n'est toujours pas défini, rbenv essaie de le définir en utilisant le contenu du ~/.rbenv/version
fichier.(Vous pouvez définir une version spécifique au projet Ruby version avec le rbenv local
, qui crée un .rbenv-version
fichier dans le répertoire courant. De même, le rbenv global
commande modifie le ~/.rbenv/version
fichier.)
Armé d'un RBENV_VERSION
variable d'environnement, rbenv ajoute ~/.rbenv/versions/$RBENV_VERSION/bin
à l'avant de votre PATH
, puis exécute la commande et les arguments passés à rbenv exec
. Voila!
Pour un aperçu détaillé de ce qui se passe sous le capot, essayez de définir RBENV_DEBUG=1
et en exécutant une commande Ruby. Chaque commande Bash exécutée par rbenv sera écrite sur votre terminal.
Maintenant, rbenv ne s'occupe que de changer de version, mais un écosystème florissant de plugins vous aidera à tout faire de installer Ruby à configurer votre environnement , gérer " gemsets " et même automatisation bundle exec
.
Je ne sais pas trop ce que le support IRC a à voir avec la commutation des versions Ruby, et rbenv est conçu pour être simple et suffisamment compréhensible pour ne pas nécessiter de support. Mais si vous avez besoin d'aide, le suivi des problèmes et Twitter ne sont qu'à quelques clics.
Divulgation: je suis l'auteur de rbenv, Ruby-build et rbenv-vars.
J'ai écrit un article détaillé: http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/
La différence fondamentale réside dans la modification de l'environnement Shell:
En outre, le problème avec RVM est qu'il couvre beaucoup plus que la simple gestion de Rubies, il a beaucoup plus que tout autre outil (il y en a d'autres que RVM et rbenv: https://Twitter.com/# !/mpapis/status/171714447910502401 )
N'oubliez pas le support instantané que vous obtenez sur IRC dans le canal "#rvm" sur les serveurs Freenode.
Donc, pour résumer les excellentes réponses ci-dessus, la principale différence pratique entre RVM et rbenv est lorsque la version de Ruby est sélectionnée.
rbenv:
rbenv ajoute une cale au début de votre chemin, une commande du même nom que Ruby. Lorsque vous tapez Ruby
sur une ligne de commande, le shim est exécuté à la place (car il est également appelé "Ruby" et vient en premier dans le chemin). Le shim recherche une variable d'environnement ou .rbenv_version
fichier pour lui dire à quelle version de Ruby à qui déléguer.
RVM:
RVM vous permet de définir une version de Ruby directement en appelant rvm use
. En outre, il remplace également la commande système cd
. Lorsque vous cd
dans un dossier contenant un .rvmrc
fichier, le code à l'intérieur du .rvmrc
le fichier est exécuté. Cela peut être utilisé pour définir une version Ruby, ou tout autre élément de votre choix.
Autres différences:
Il y a bien sûr d'autres différences. RVM a des gemmes prêts à l'emploi, tandis que rbenv nécessite juste un peu plus de piratage (mais pas beaucoup). Les deux sont des solutions fonctionnelles au problème.
La principale différence semble être quand et comment Ruby est changé . Ruby est changé:
RVM s'appuie sur la commande cd
modifiée et la sélection manuelle de Ruby by rvm use
. rbenv utilise des wrappers ou "shims" pour toutes les commandes de base Ruby comme mécanisme par défaut pour sélectionner Ruby. RVM crée des wrappers pour les outils de ligne de commande de base comme gem, rake, Ruby, aussi. Ils sont utilisés pour exemple dans CronJobs (voir http://rvm.io/integration/cron/ ), mais ils ne sont pas le mécanisme par défaut pour changer la version Ruby.
Ainsi, les deux méthodes sélectionnent "automatiquement" la bonne Ruby en écrasant les commandes et en utilisant des wrappers. Rvm remplace les commandes Shell comme cd. Rbenv remplace toutes les commandes de base Ruby commandes telles que comme rubis, irb, râteau et gemme.
rvm system
env > before
rvm jruby # or whatever
env > after
diff after before
Vous donne approximativement:
< 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
Et cela précède:
$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/jruby-1.6.6@global/bin
à $PATH