Ruby development with rbenv
rbenv
is a tool that manage multiple Ruby version environment. It's a simple, lightweight alternative to RVM
.
How it works
rbenv
intercept Ruby commands using shim
, which located in the ~/.rbenv/shims
, executables injected to the OS PATH
, determines which Ruby version is used and pass the commands to that Ruby version installation. Each version of Ruby is installed in the ~/.rbenv/versions
directory.
Understanding PATH
When some command like ruby
or rails
is invoked, the operating system search through a list of directories to find an executable file with that name. This list of directories lives is maintained in an environment variable called PATH
, with each directory in the list is separated by a colon:
/usr/local/bin:/usr/bin:/bin
Directories in PATH
are searched from left to right, so a matching executable file in a directory at the beginning of the list takes precedence over another one at the end. The /usr/local/bin
directory will be searched first, then /usr/bin
, then /bin
in the previous PATH variable.
Understanding Shims
rbenv
works by inserting a directory of shims in front of the PATH
variable:
~/.rbenv/shims:/usr/local/bin:/usr/bin:/bin
Through the rehashing process, rbenv maintains shims in the ~/.rbenv/shims
directory to match every Ruby command across every installed version of Ruby like: irb
, gem
, rake
, bundle
, rails
, ruby
...
Shims are lightweight executables that simply pass these command to rbenv. So with rbenv installed, when a command like rake
is called, the operating system will do the following:
Search through the
PATH
variable for an executable file namedrake
Find the rbenv shim named
rake
at the beginning of thePATH
Run the shim named
rake
, which in turn passes the command along to rbenv
All the shims have the same content:
#!/usr/bin/env bash
set -e
[ -n "$RBENV_DEBUG" ] && set -x
program="${0##*/}"
if [ "$program" = "ruby" ]; then
for arg; do
case "$arg" in
-e* | -- ) break ;;
*/* )
if [ -f "$arg" ]; then
export RBENV_DIR="${arg%/*}"
break
fi
;;
esac
done
fi
export RBENV_ROOT="~/.rbenv"
exec "~/.rbenv/libexec/rbenv" exec "$program" "$@"
Installation
Note: rbenv
isn't compatible with RVM. If RVM got installed in the system, it need to be removed all references to it:
rvm implode
This will remove the rvm/
directory and all the rubies built within it.
gem uninstall rvm
This will remove the final trace of rvm.
Check the .bashrc
, .profile
and .bash_profile
files to make sure there aren't any trace of RVM as well.
Let's begin:
Cloning the GitHub repository into
~/.rbenv
:$ cd $ git clone git://github.com/sstephenson/rbenv.git .rbenv
Add ~/.rbenv/bin to the $PATH for access to the
rbenv
command-line utility.$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
Add
rbenv init
to the shell to enable shims and autocompletion$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
Restart the shell to have rbenv and autocompletion:
$ exec $SHELL
Ubuntu Desktop note: Modify ~/.bashrc instead of ~/.bash_profile
How rbenv hooks into the shell
rbenv init
is the only command that load extra commands into the shell. It simply does:
Sets up the shims path. This can be manually done by prepending
~/.rbenv/shims
to the $PATH variable.Installs autocompletion. Sourcing
~/.rbenv/completions/rbenv.bash
will set that upRehashes shims automatically (or run manually with
rbenv rehash
).Installs the sh dispatcher. This allows
rbenv
and plugins to change variables in the current shell.
Run rbenv init -
to see exactly what happens under the hood.
Installing Ruby version
Optional: Install ruby-build, which provides the rbenv install
command that simplifies the process of installing new Ruby versions. Then use it to install new Ruby version:
# list all available versions:
$ rbenv install -l
# install a Ruby version:
$ rbenv install 2.2.2
Or manually install Ruby:
Create new folder in home directory to keep Ruby version's source code in:
$ cd $ mkdir rbversions
Download the latest version of the Ruby source code
$ curl -O http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.2.tar.gz
Unpack the download then
cd
into the newly extracted folder:$ tar xzvf ruby-2.2.2.tar.gz $ cd ruby-2.2.2
Run configure,
make
andmake install
making sure the correct version number in the./configure --prefix
path is entered:$ ./configure --prefix=$HOME/.rbenv/versions/2.2.2 $ make $ make install
Now, Ruby 2.2.2 is installed in the
~/.rbenv/versions/2.2.2
directory.Run
rbenv rehash
to rebuild the shim binaries. It’s recommended to do this anytime a new Ruby binary is installed (new Ruby version or gem that comes with a binary).
Uninstalling Ruby Versions
To remove old Ruby versions, simply rm -rf
the directory of that Ruby version. To find the directory of a particular Ruby version, use the command:
rbenv prefix `version(2.2.2)`
The ruby-build plugin provides an rbenv uninstall
command to automate the removal process.
Ruby version control
When a shim is executed, rbenv
determines which Ruby version to use by reading from the following sources, in this order:
The
RBENV_VERSION
environment variable, if specified. Therbenv shell
command can be used to set this environment variable in the current shell session.rbenv shell 2.2.1
Behind the scenes the
RBENV_VERSION
environment variable is set to point to the Ruby version which is specified in the command:$ echo $RBENV_VERSION 2.2.1
The first
.ruby-version
file found by searching the current working directory and each of its parent directories until reaching the root of the filesystem. The.ruby-version
in the current directory can be modified with the commandrbenv local
.$ cd ~/projects/foobar $ rbenv local 2.2.1
This writes the version to a file .rbenv-version in the current directory:
$ cat .rbenv-version 2.2.1
The global
~/.rbenv/version
file is the last place forrbenv
to look up. This file can be modified using therbenv global
command. If the global version file is not present, rbenv assumes the "system" Ruby (whatever version should be run) will be used.$ rbenv global 2.2.1
This will write the Ruby version to
~/.rbenv/version
$ cat ~/.rbenv/version 2.2.1
Locating the Ruby Installation
Each Ruby version is installed into its own directory under ~/.rbenv/versions
. Example:
~/.rbenv/versions/2.2.1/
~/.rbenv/versions/2.1.0/
~/.rbenv/versions/1.9.3-p327/
To see all the versions of Ruby that have installed and available to rbenv there’s the rbenv versions
command. This lists all the versions of Ruby that rbenv knows about and adds an asterisk next to the current active version based on the current context e.g. shell, local or global. Let's see how the output of this command changes when the context is changed as well.
$ cd
$ rbenv versions
system
2.1.2
* 2.2.1 (set by ~/.rbenv/version)
$ cd ruby_projects/foo
$ rbenv versions
system
* 2.1.2 (set by ~/ruby_projects/foo/.ruby-version)
2.2.1
$ rbenv shell 2.2.1
$ rbenv versions
system
2.1.2
* 2.2.1 (set by RBENV_VERSION environment variable)
Source: Up and Running with rbenv, rbenv home page