更多关于“为什么”和“wtf”而不是“如何”。
多年来,RubyGems 开发团队收到了很多支持请求,这是一个列表,其中包含新老用户经常提出的问题。
- 我使用
--user-install
安装了宝石,但它们的命令不可用 - 如何信任自动下载的 Gem 代码?
- 为什么
require 'some-gem'
失败? - 为什么从宝石加载文件时 require 返回 false?
我们也回答了 Bundler.io Slack 上的问题。您可以在支持网站上找到的一些信息包括
我使用 --user-install
安装了宝石,但它们的命令不可用 —————————————————————————
当您使用 --user-install
选项时,RubyGems 会将 gems 安装到您主目录内的某个目录,例如 ~/.gem/ruby/1.9.1
。您安装的 gems 提供的命令最终会出现在 ~/.gem/ruby/1.9.1/bin
中。为了让您能够使用这些安装的程序,您需要将 ~/.gem/ruby/1.9.1/bin
添加到您的 PATH
环境变量中。
例如,如果您使用 bash,您可以通过将以下代码添加到您的 ~/.bashrc
文件中,将该目录添加到您的 PATH
中。
if which ruby >/dev/null && which gem >/dev/null; then
PATH="$(ruby -r rubygems -e 'puts Gem.user_dir')/bin:$PATH"
fi
将此代码添加到您的 ~/.bashrc
文件后,您需要重新启动 shell 以使更改生效。您可以通过打开一个新的终端窗口或在您已经打开的窗口中运行 exec $SHELL
来实现这一点。
如何信任自动下载的 Gem 代码?
就像您无法完全信任从网络上安装的任何其他代码一样,您也无法完全信任 gems。您有责任了解您正在使用的 gems 的来源。在安全至关重要的环境中,您应该只使用已知可靠的 gems,并可能对 gem 代码进行自己的安全审计。
Ruby 社区正在讨论如何使用一些公钥基础设施来提高 gem 代码的安全性。要查看此讨论的进展,请访问 GitHub 上的 rubygems-trust 组织。
为什么 require 'some-gem'
失败?
并非每个库都具有 gem 名称与您需要 require 的文件名称之间的严格映射。首先,您应该检查文件是否正确匹配。
$ gem list RedCloth
*** LOCAL GEMS ***
RedCloth (4.1.1)
$ ruby -e 'require "RedCloth"'
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- RedCloth (LoadError)
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
from -e:1
$ gem contents --no-prefix RedCloth | grep lib
lib/case_sensitive_require/RedCloth.rb
lib/redcloth/erb_extension.rb
lib/redcloth/formatters/base.rb
lib/redcloth/formatters/html.rb
lib/redcloth/formatters/latex.rb
lib/redcloth/formatters/latex_entities.yml
lib/redcloth/textile_doc.rb
lib/redcloth/version.rb
lib/redcloth.rb
$ ruby -e 'require "redcloth"'
$ # success!
如果您正在 require 正确的文件,那么可能是 gem
使用的 ruby 版本与 ruby
不同。
$ which ruby
/usr/local/bin/ruby
$ gem env | grep 'RUBY EXECUTABLE'
- RUBY EXECUTABLE: /usr/local/bin/ruby1.9
在这种情况下,我们有两个 ruby 安装,因此 gem
使用的版本与 ruby
不同。您可以通过调整符号链接来解决此问题。
$ ls -l /usr/local/bin/ruby*
lrwxr-xr-x 1 root wheel 76 Jan 20 2010 /usr/local/bin/ruby@ -> /usr/local/bin/ruby1.8
-rwxr-xr-x 1 root wheel 1213160 Jul 15 16:36 /usr/local/bin/ruby1.8*
-rwxr-xr-x 1 root wheel 2698624 Jul 6 19:30 /usr/local/bin/ruby1.9*
$ ls -l /usr/local/bin/gem*
lrwxr-xr-x 1 root wheel 76 Jan 20 2010 /usr/local/bin/gem@ -> /usr/local/bin/gem1.9
-rwxr-xr-x 1 root wheel 550 Jul 15 16:36 /usr/local/bin/gem1.8*
-rwxr-xr-x 1 root wheel 550 Jul 6 19:30 /usr/local/bin/gem1.9*
您可能还需要对 irb
进行相同的处理。
为什么从宝石加载文件时 require 返回 false?
从 gem 加载文件时,require 返回 false。通常,require 在正确加载时会返回 true。这是怎么回事?
没什么问题。好吧,有点问题。但没什么需要你担心的。
require 方法返回 false 并不表示错误。它只是意味着该文件已经加载过了。
RubyGems 有一个功能,允许在激活(即选择)一个 gem 时自动加载文件。当你 require 一个处于非激活 gem 中的文件时,RubyGems 软件会为你激活该 gem。在激活过程中,任何自动加载的文件都会被加载。
因此,当你的 require 语句实际执行加载文件的工作时,该文件已经通过 gem 激活自动加载了,因此语句返回 false。