如何要求rubygems帮助找到rubygem文件?

时间:2011-05-30 23:52:05

标签: ruby rubygems

在尝试解决Gem found in irb, not in Ruby时,我尝试了解require 'rubygems'对我自己安装的影响:

$ irb
irb(main):001:0> RUBY_VERSION
=> "1.8.7"
irb(main):002:0> $:
["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/x86_64-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/x86_64-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/x86_64-linux", "."]
=> nil
irb(main):003:0> require "rubygems" # Hasn't been required already
=> true
irb(main):004:0> require "rubygems" # Will return false, because it's already been required
=> false
irb(main):005:0> $: # Same as before
=> ["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/x86_64-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/x86_64-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/x86_64-linux", "."]

如果要求rubygems不修改$:,那么它如何帮助查找文件?是monkeypatch require吗?如果是这样,它使用什么变量来查找安装了rubygem的库?

1 个答案:

答案 0 :(得分:13)

以下是相关来源的当前版本:https://github.com/rubygems/rubygems/blob/02ead548e38ff90923444fa7c0ff9f6a5dbd87b0/lib/rubygems/custom_require.rb。 (编辑:here's an earlier version (1.5.2)更清楚地表达发生的事情。)

文档说:

  

当需要RubyGems时,Kernel#require将替换为我们自己的   能够根据需要装载宝石。

     

当您致电require 'x'时,会发生以下情况:

     
      
  • 如果文件可以从现有的Ruby加载路径加载,那么   是
  •   
  • 否则,将搜索已安装的gem以查找匹配的文件。   如果它在宝石'y'中找到,则该宝石被激活(添加到   loadpath)。
  •   
     

返回false if的正常require功能   已保存该文件。

这样做是通过打开module Kernel并使用alias gem_original_require require别名原始需求,然后重新定义require以首先调用原始版本,并查看宝石,如果不是工作

因此,只有在需要gem时才会更改加载路径:

ruby-1.8.7-p330 :002 > $:.length
=> 9 
ruby-1.8.7-p330 :003 > require 'rubygems'
=> true 
ruby-1.8.7-p330 :004 > $:.length
=> 9 
ruby-1.8.7-p330 :005 > require 'haml'
=> true 
ruby-1.8.7-p330 :006 > $:.length
=> 10