I recently needed to install a couple of things with gem on my MBP, and ran into two issues. Writing this down as a record for the next time I hit the same problems.

The first is the “Connection Reset” problem. The symptom is simple: after running gem install, it looks like this:

Bash
gem install xxx
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://api.rubygems.org/quick/Marshal.4.8/xxx.gemspec.rz)

The cause is simple too: in China, api.rubygems.org is blocked — who knows why.

The easiest fix is to use a mirror.

The Taobao mirror URL was: https://ruby.taobao.org/

The Taobao mirror homepage used to explain it in detail.

Taobao no longer maintains it. Following the redirect, you can currently use Ruby China. But knowing how these things tend to go...

If you install manually with gem, this command will do the trick:

Bash
$ gem sources --add https://gems.ruby-china.com --remove https://rubygems.org/
$ gem sources -l
*** CURRENT SOURCES ***

https://gems.ruby-china.com
# 请确保只有 gems.ruby-china.com
# 若发现还有 ruby.taobao.org,可以再删除下:
# $ gem sources --remove https://ruby.taobao.org
$ gem install xxx

It basically modifies your ~/.gemrc file.

If you use bundler, run:

Bash
bundle config mirror.https://rubygems.org https://gems.ruby-china.com

On OS X, if you then continue with gem install, you’ll easily run into a permission error like this:

Bash
gem install xxx
1 gem installed
gem install xxx
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.

The reason is exactly what it says: gem is trying to write files to some magic directory, but you don’t have permission. That’s because you’re using Apple’s built-in Ruby and trying to drop things into Apple’s own libraries, which are owned by root by default.

There are two suboptimal ways to fix this. One is to prefix with sudo. Remember to redo the source-switching step with sudo first. The other is to change the owner of /Library/Ruby/Gems/2.0.0, i.e.

Bash
sudo chown -R $(whoami) /Library/Ruby/Gems/2.0.0

As versions change, Apple’s system libraries change too. For example, on 10.14.2 the Ruby version is 2.3.0. Adjust accordingly.

Either way, you’re forcing that directory writable. The problem is that this library is used by the system at runtime; if you mess it up, it’s hard to clean up.

My personal recommendation is to install another Ruby with homebrew, so local stays local and system stays system. It’s not that big anyway. Also, if you update the system Ruby yourself and run into compatibility issues, fixing them can be a real pain.

The official Homebrew installation guide is very detailed on the official website, so I won't repeat it here. Just a quick note: if you're a new user, after installation, make sure that in your PATH environment variable — the program search path list — /usr/local/bin comes before /usr/bin.

Generally, on Linux/Unix systems, programs use the PATH environment variable as the search path list. This environment variable uses a colon to separate the ordered multiple paths. Whenever you type a command, the program will try to look up each path mentioned in PATH one by one and execute the first executable file with the corresponding name.

We can simply use the command echo $PATH to view the current path list.

If you don't understand, that's fine too — you can run brew doctor after installation. It will perform a series of environment-related checks and give you a lot of constructive suggestions. There should also be some relevant notes about PATH environment variable issues, which can serve as a further reference.

Once brew is ready, installing ruby takes just one command:

Bash
brew install ruby

Then install with gem:

Bash
$ gem install tmbundle-manager
Fetching: thor-0.19.1.gem (100%)
Successfully installed thor-0.19.1
Fetching: tmbundle-manager-0.1.2.gem (100%)
Successfully installed tmbundle-manager-0.1.2
Parsing documentation for thor-0.19.1
Installing ri documentation for thor-0.19.1
Parsing documentation for tmbundle-manager-0.1.2
Installing ri documentation for tmbundle-manager-0.1.2
Done installing documentation for thor, tmbundle-manager after 1 seconds
2 gems installed

By default, brew's various gems will be installed to /usr/local/lib/ruby/gems/2.3.0. 2.3.0 is the version number; it might be in a different location. Not the original /Library/Ruby/Gems/2.0.0 location.

Then let's check gem and find that the bundled one and the system one use completely separate sets of libraries. Very nice.

Bash
$ which gem
/usr/local/bin/gem
$ gem list --local

*** LOCAL GEMS ***

bigdecimal (1.2.8)
did_you_mean (1.0.0)
io-console (0.4.5)
json (1.8.3)
minitest (5.8.3)
net-telnet (0.1.1)
power_assert (0.2.6)
psych (2.0.17)
rake (10.4.2)
rdoc (4.2.1)
test-unit (3.1.5)
thor (0.19.1)
tmbundle-manager (0.1.2)

$ /usr/bin/gem list --local

*** LOCAL GEMS ***

activesupport (3.2.19)
bigdecimal (1.2.0)
CFPropertyList (2.2.8)
colored (1.2)
i18n (0.6.11)
io-console (0.4.2)
json (1.7.7)
libxml-ruby (2.6.0)
minitest (4.3.2)
multi_json (1.10.1)
nokogiri (1.5.6)
psych (2.0.0)
rake (0.9.6)
rdoc (4.0.0)
rubygems-update (2.4.2)
sqlite3 (1.3.7)
test-unit (2.0.0.0)
xcodeproj (0.19.4)

Addendum: If you’re still unfamiliar with configuring PATH, or interested in how the mechanism works, you can refer to here. Bird's Private Kitchen (鸟哥的私房菜) is arguably what first introduced many beginners to the terminal. And as a Fedora fan, my affinity for his book definitely has a lot to do with the fact that it uses Red Hat’s CentOS.