Disclaimer: At the time of writing, additional configuration was required to get rbenv to work nicely with fish. Further work has been done since and today rbenv should work out of the box with fish without any further configuartion
Now that we have a pretty decent shell, it’s time to hook it up with our favourite tools. My choice of Ruby version management tool is rbenv. It does one thing and it does it right. Period.
To get rbenv working with the fish shell is actually relatively simple but I’d like to take the opportunity to explain why it did not necessarily work out of the box with fish. I’m hoping this will help you understand the common problem better when you’ll integrate other tools with fish.
Understanding the differences between POSIX shells and fish
Most people use bash or zsh and add the following to their shell configuration file:
eval "$(rbenv init -)"
This works just fine in those cases, however whilst fish tries to maintain backwards compatibility it often introduces either new concepts or implements existing ones differently.
Fish is by design NOT a 100% POSIX-compatible shell and so it won’t understand the
$ function that creates a sub shell. It also uses
set instead of
export to set environment variables.
There's nothing special about the initialization of the shell, simply the output of
rbenv init - is evaluated in runtime. Subsequently the trick is to get
rbenv init - to produce output that fish will understand. Luckily for us rbenv supports the fish shell in master since this commit. rbenv's shims work fine with fish or any other shell, since even there's a dependency on bash, it does not have to be your shell of choice, it just has to be accessible for invocation.
Tell rbenv to go fishing
So turns out that fish shell support is baked into rbenv already but currently as of the writing it sits on the github master and hasn't been officially released. Worry not, installing HEAD versions with our favourite OS X package manager, Homebrew is a breeze:
$ brew install rbenv --HEAD
NOTE: In case you had rbenv installed already, you can safely uninstall it before you’d install rbenv HEAD, it won’t remove your installed rubies.
Now let’s add the following to our shell configuration,
set -gx RBENV_ROOT /usr/local/var/rbenv . (rbenv init -|psub)
The former line sets a global
RBENV_ROOT variable and exports it. This is being picked up by rbenv and so it installs Rubies into the Homebrew directory. The second one evals the right output of
rbenv init - as explained above.
After you're done with these open up a new shell and verify that rbenv is properly installed:
$ type rbenv rbenv is a function with definition
Now let's install ruby-build as well so that we can install Ruby versions:
$ brew install ruby-build
Now it's time to get some Rubies installed:
$ rbenv install 2.0.0-p353
Installing Ruby 2.1.0 with rbenv and ruby-build now
It's been only a couple of minutes and Ruby 2.1.0-p0 is available via the ruby-build master. If you want to install it (and why wouldn't you?!) you just install ruby-build master using Homebrew:
$ brew uninstall ruby-build $ brew install ruby-build --HEAD
And then it's available via rbenv:
$ rbenv install 2.1.0-p0
I'm a Ruby/JS dev/trainer with a focus on quality. An ex-Londoner, @terracycle, @ubxd, @lastfm. Follow me at http://twitter.com/attilagyorffy