I saw an excellent post by Jacob Kaplan-Moss (blog) about how he sets up his Python environment. Setting up your development environment is confusing when you’re new to a language. There seem to be a number of virtual environment options, and it is difficult figure out the best path. His blog post My Python Environment was a huge help to me. So I mentioned him on Twitter (@jacobian) to thank him. He wrote me back and suggested I do the same thing for Ruby. I just started a new job, so it’s a perfect time to repay the favor.

My requirements are similar to @jacobian
- Manage multiple ruby versions so that I can work on projects that have different versions of Ruby. Ruby version can vary enough to be non-compatible, even across minor revisions (2.x to 2.y)
- Avoid using the system version. It rarely matches the version that I need when working on an application.
- Avoid dependency hell: manage each environment depending on the version of Ruby
The following instructions assume OSX Catalina.
Manage Multiple Ruby Versions
I use rbenv to manage different Ruby versions.
- Install HomeBrew using
/bin/bash -c ...
https://brew.sh/ - Install rbenv with HomeBrew on OSX: (instructions)
- Per the instructions: don’t forget to add
eval "$(rbenv init -)"
to your .bash_profile (.zshrc if you’re using z-shell) - Installing rbenv will also install ruby-build. This is necessary, as ruby-build makes it easy to install different rubies.
- NOTE: A case could be made for RVM as well. From what I’ve seen most Linux production installations use RVM since it works better in a multi-user environment. But for my personal machine rbenv is cleaner and simpler than RVM.
- Per the instructions: don’t forget to add
- Install openssl with HomeBrew:
brew install openssl
- ruby-build requires openssl when installing some of the more recent versions of Ruby
- Some helpful rbenv commands
- List all available Ruby versions:
rbenv install --list-all
- Install a version:
rbenv install <version name>
(e.g.rbenv install 2.6.6
)
- List all available Ruby versions:
Handle Dependencies
I like to “vendor” my gems as a way to prevent “dependency hell”. In other words, I like to keep a copy of the gem with the project, rather than storing all of the gems with the ruby version. Since I started vendoring gems, I rarely get into serious trouble with gem dependencies. It uses more space on your hard disk, because you are storing multiple copies of the same gem, but the benefits out-weigh the costs.
- Fine-grained version control using the Gemfile. Different versions of dependencies can be maintained within the same Ruby version.
- Gem analysis. I can go in and easily inspect the source code for a gem by viewing it in the <project root>/vendor directory. This is much easier than spelunking through the gem directory tree.
The easiest way to vendor gems is to create a few aliases. I have the following aliases created.
# Bundler
alias b="bundle"
alias bi="b install --path vendor"
alias bil="bi --local"
alias bu="b update"
alias be="b exec"
alias binit="bi && b package && echo 'vendor/ruby' >> .gitignore"
Now, when I’m in a project I’ll type bi
rather than bundle
or bundle install
Further more, I have a few Rails specific ones. It’s just more fun to type bake
🙂
# Bundler Rails
alias bails="be rails"
alias bake="be rake"
alias bspec="be rspec"
I you need more justification here is an excellent blog post on vendoring gems
Start a New Project
I typically use the following flow for any Ruby development (other than Rails).
- Create a new project folder and cd into it
- Create a .ruby-version file with the desired version of ruby. rbenv will evaluate this file when cd’ing into the directory and will automatically switch to the specified version of Ruby.
- Initialize bundler to help with dependency management. This will create a Gemfile. Bundler uses the Gemfile to determine with dependencies need to be installed.
- Add the necessary gems
- Install the gems
# Step 1
mkdir demo
cd demo
# Step 2
echo 2.6.6 > .ruby-version
cd .
ruby -v # verify
# Step 3
bundle init
For Rails development, I’ve started using this command:
rails new <app name> \
—skip-coffee \
—skip-action-cable \
—database=postgresql \
—skip-sprockets \
—webpack
--skip-bundle
Then cd into the project directory and run bi
. Skipping bundle
lets you vendor the gems and prevents the gems from being installed into your Ruby version namespace.