Homebrew install Ruby keg-only can't find gem

2019-04-14 06:22发布

How do I get irb to work after installing Ruby with Homebrew?

When I try to run irb, I get an error:

$ irb
Traceback (most recent call last):
    2: from /usr/local/opt/ruby/bin/irb:23:in `<main>'
    1: from /usr/local/lib/ruby/site_ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
/usr/local/lib/ruby/site_ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': can't find gem irb (>= 0.a) with executable irb (Gem::GemNotFoundException)

I tried:

$ brew link ruby
Warning: Refusing to link macOS-provided software: ruby
If you need to have ruby first in your PATH run:
  echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.bash_profile

For compilers to find ruby you may need to set:
  export LDFLAGS="-L/usr/local/opt/ruby/lib"
  export CPPFLAGS="-I/usr/local/opt/ruby/include"

I have the lines below at the top of my /etc/paths file:

/usr/local/bin
/usr/local/opt/ruby/bin
/usr/local/lib/ruby/gems/2.6.0/bin

irb doesn't show up in the output of gem list, but:

$ find /usr/local -name irb
/usr/local/lib/ruby/2.6.0/irb
/usr/local/Cellar/ruby/2.6.0_1/bin/irb
/usr/local/Cellar/ruby/2.6.0_1/lib/ruby/2.6.0/irb
/usr/local/Cellar/ruby/2.6.0_1/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb
/usr/local/Cellar/ruby/2.6.0_1/share/ri/2.6.0/system/lib/irb

I'm also having a similar issue with ri & rdoc.

2条回答
ゆ 、 Hurt°
2楼-- · 2019-04-14 06:48

Run: gem install irb and you now good to go.

查看更多
唯我独甜
3楼-- · 2019-04-14 06:52

Assuming you're using Homebrew Ruby...

The irb executable is located at:

/usr/local/opt/ruby/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb

You can use that line directly, symlink it into your $PATH, alias it, or whatever.


Alternatively, you may patch /usr/local/opt/ruby/bin/irb around line 22.

# patch
class Gem::BasicSpecification
  def self.default_specifications_dir
    File.join(Gem.private_dir, "specifications", "default")
  end
end
# /patch

# Next line looks like this. Don't change this.
# if Gem.respond_to?(:activate_bin_path)

You may do the same in /usr/local/opt/ruby/bin/ri and /usr/local/opt/ruby/bin/rdoc to patch those commands as well.

Why?

See https://github.com/Homebrew/homebrew-core/blob/955497722b9bf65069957b0e7c903b96939cdd99/Formula/ruby.rb#L112

The Homebrew Ruby formula assumes all gems will be installed in the "global gem directory" /usr/local/lib/ruby/gems/2.6.0/. So when you uninstall-reinstall Homebrew Ruby, the gems stick around - you don't have to re-install them as well (kinda annoying since I have gems installed for Ruby versions I don't even have installed anymore, but that's another issue).

But Ruby's default gems aren't in the global gem dir. They're inside the Ruby installation dir (what the Homebrew formula refers to as the private_dir) : /usr/local/opt/ruby/lib/ruby/gems/2.6.0/.

So Homebrew Ruby can't find them.

Homebrew patches Rubygems, so this snippet patches Rubygems again, but deeper. You can also patch-patch like this:

module Gem
  def self.default_dir
    private_dir  
  end
end

But default_dir is used in other places and I didn't want to break anything.

查看更多
登录 后发表回答