New Mac Problems
As you may or may not know, macOS comes with a version of Ruby installed ( 2.3.3 released 11/21/2016). But something surprised me on my newest MacBook when I tried to install
rspec… my terminal gave me the following permission error:
Fetching: rspec-3.7.0.gem (100%) ERROR: While executing gem ... (Gem::FilePermissionError) You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.
My experience in Ruby is quite limited - I started learning it ~2 years ago because it was the language to learn as a beginning programmer (the community is very supportive and there are a lot of learning resources posted all over the internet). I abandoned it to learn other programming languages after I began doubting it’s usefulness to me. I still remember a lot of the syntax and behavior, but one thing I do not remember is having to use
sudo to install
rspec when I was trying to learn TDD.
At first I thought my MacBook permissions got messed up because I had created a new admin user and deleted the original. Turns out, I was wrong. After a format and fresh install of macOS, the problem I was having still remained. This is due to macOS including Ruby inside the root file system so when trying to install a new gem, it attempts to install it within a root directory. The permission problem occurs because each individual user only has full read/write permissions within their home directory and only has read permissions for the root directory. Someone else in my internship program pointed out having the same problem and it was recommended that they use
rbenv. So I decided to check it out.
Installing rbenv with Homebrew
Following the installation instructions on the README of the
rbenv Github repo, it was fairly painless to install using
- First, install
homebrewby running the following command in your terminal:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
rbenvby running the
brew install rbenvcommand.
rbenvby running the
Of course, I didn’t read anything else in the README until after I tried to install
rspec again and got the same permission error. As it turns out, the README file does an excellent job of explaining how
rbenv works and how to use it.
Behind the Scenes
rbenv manages different versions of Ruby on your computer. With
rbenv, you can run 2.2.1 ruby code in one project and 2.4.3 ruby code in another project. It essentially works by intercepting the commands you run from your terminal. Everytime you run an executable in Terminal without specifying the full directory path where that executable is stored (using the
rspec, etc,..), your terminal searches the list of directories specified in your in a system-wide environment variable called
PATH. Using the
echo $PATH command in a bash Terminal will return that list, with each directory separated by a colon (the default
PATH in macOS High Sierra is
/usr/local/bin:/usr/bin:/usr/sbin/:/sbin/). You can use the
ls command to peak into any of these directories and you should see some familiar binaries (executables). Installing
rbenv modifies the
PATH variable, adding it’s own directory before any of the others. Because your Terminal searches through each sequentially until it finds a match,
rbenv can then begin to intercept commands.
Installing Ruby with rbenv
Now, let’s walk through how to install the latest version of Ruby using
rbenv and make it the system-wide default. Running the
rbenv install -l command returns a list of all the Ruby versions available in
rbenv. At the time of writing, 2.5.1 was the latest version of Ruby, so running
rbenv install 2.5.1 should return something similar to:
$ rbenv install 2.5.1 ruby-build: use openssl from homebrew Downloading ruby-2.5.1.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2 Installing ruby-2.5.1... Installed ruby-2.5.1 to /Users/tim/.rbenv/versions/2.5.1
Changing Your Default Ruby Version with rbenv
Now, check the current system-wide default by using
rbenv global (and/or
ruby -v to check the current default version) and then set a new default using the same command with an added version parameter (
rbenv global 2.5.1), and double check that the default version was updated using
rbenv global and/or
ruby -v (if either of these commands return the wrong version, try opening a new terminal window, and reissuing the commands):
$ rbenv global system $ ruby -v ruby 2.3.3p222 (2016-11-21 revision 56859) [universal.x86_64-darwin17] $ rbenv global 2.5.1 $ rbenv global 2.5.1 $ ruby -v ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
Success! The latest version of Ruby is now the system-wide default! If you’d like to find out more about what
rbenv can do (such as using a different Ruby version for different projects), be sure to checkout the official README.