rubygem的小细节

我在linux上安装了rubygem以后, 发现一个问题,单独写的ruby文件无法以相对路径require gem上的包
比如
require 'something' 不行,必须以绝对路径 require '/usr/local....../something' 才可以
我查询了ruby的loadpath ("$:") ,发现这个路径并不在RUBY的loadpath中, 按道理说不能require是正确的

但是为什么在我的windows上面或者在rubyonrails程序中的就可以这样require了呢,经过一番google再加上自己多次试验,终于发现了其中的缘故

原来windowsXP下面有一个环境变量 RUBYOPT='rubygems' 而linux下面没有, 在linux下面加上RUBYOPT以后,发现可以工作, 进一步发现只要在require其他类以前先require 'rubygems' 程序也能自动识别gem包内的库, 看来,rubygems 对require函数作了手脚, 总结如下

RUBYOPT中'rubygems' 实际上引用的是 ubygems.rb这个文件,在ubygems.rb中再require 'rubygems' 相当于作了一个alias

在rubygems.rb中, 对Kernel模块作了如下调整
1增加了require_gem的指令,这个指令支持按照指定版本号require
2在文件末尾, require了 'custom_require'

在custom_require.rb中, 对require函数作了修改,代码如下

module Kernel 
  alias require__ require 
  
  
def  require(path) 
    require__ path 
  rescue LoadError 
=>  load_error 
    begin 
      @gempath_searcher 
||=  Gem::GemPathSearcher.new 
      
if  spec  =  @gempath_searcher.find(path) 
        Gem.activate(spec.name, true, 
" = #{spec.version} "
        require__ path 
      
else  
        
raise  load_error 
      end 
    end 
  end 
end 


在上面的代码中, require函数被更新, 当不能从RUBY内部的loadpath中读取文件时, require会从gempath中查找, 这样require函数就能支持gem了

结论: 要使用gem中的包, 3个办法
1 使用RUBYOPT='rubygems'
2 先require 'rubygems' 或者 'ubygems'
3 使用require_gem

你可能感兴趣的:(Ruby)