2011-05-30 20 views
9

在試圖解決Gem found in irb, not in Ruby,我試着看到了我自己安裝什麼樣的影響require 'rubygems'要求rubygems如何幫助找到rubygem文件?

$ 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", "."] 

如果requring RubyGems的不修改$:,那麼它是如何幫助查找文件?它是否monkeypatch require?如果是這樣,它使用什麼變量來查找rubygem安裝的庫?

回答

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 loadpath被加載,它 是。
  • 否則,搜索已安裝的寶石以查找匹配的文件。 如果在gem'y'中找到該寶石,則激活該寶石(添加到 加載路徑中)。

如果該文件已加載 被保留返回false的正常require功能。

它通過開放module Kernel和走樣原來需要與alias gem_original_require require,然後重新定義require首先調用原始版本,並期待在寶石如果不工作這一點。

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 
+0

你知道它使用什麼樣的變量:

所以,當你需要一個寶石負載路徑僅改變了嗎? – 2011-05-31 08:34:39

+1

@Andrew'Gem.path'可能就是你要找的東西。 – matt 2011-05-31 14:43:43