负载方便的要求

时间:2018-04-30 09:47:19

标签: ruby

require加载一个rubygem,但它在新文件或更改时找不到/重新加载文件(例如:如果你发出gem install x安装了新的requireable / loadable文件,但是{{1找不到它。)

require

另一方面,require 'json' #=> true require 'json' #=> false 可以重新加载文件。

load

但是,load 'path/to/json.rb' #=> true load 'path/to/json.rb' #=> true 需要指向ruby文件的路径,而load可以灵活地在默认位置找到它。

在给定rubygem名称的情况下,是否有一个中间函数require可以返回要加载的文件的路径? (确实,f返回它而不仅仅是require会很方便,但这不是它编码的方式。)所以我可以这样称呼它:

true

1 个答案:

答案 0 :(得分:2)

require将尝试不同的扩展名(例如.rb。,。so,.dll等),以便在给定的路径不是绝对路径时,在$LOAD_PATH中找到您需要的文件,例如

require 'json' # this will try 'json.rb' first
当路径不是绝对路径时,

load也会搜索$LOAD_PATH,但它不会尝试为您添加任何扩展名,而是您必须具体说明它,例如

load 'json.rb'

如果您想知道该文件的加载位置,可以使用Gem::Specification类,如下所示:

Gem::Specification.find_by_name('json').full_gem_path

这将返回文件目录的路径loadedrequired

免责声明:以下内容仅供修改之用,不得用于任何类型的生产代码

如果你真的想要这样的东西,你可以尝试:

module Kernel 
  def load_and_print_gem(gem_name, *requirements)
    begin 
      spec = Gem::Specification.find_by_name(gem_name, *requirements)
      path = File.join(spec.full_gem_path, 'lib', "#{gem_name}.rb") 
      puts "Loading #{gem_name} from Gem::Specification: #{path}" if File.exist?(path)
      load path
    rescue Gem::MissingSpecError, LoadError => e 
      if path = $LOAD_PATH.find {|p| Dir.glob("#{p}/**/#{gem_name}.rb").any? }
        puts "Loading #{gem_name} from $LOAD_PATH: #{path}/#{gem_name}.rb" 
      end
      load File.join(path.to_s,"#{gem_name}.rb")
    end
  end
end

注意:$LOAD_PATH后退将加载它找到的第一个.rb文件与gem_name匹配,不一定是最新的宝石版本,如果有超过$LOAD_PATH个目录中的1个

然后

load_and_print_gem('json') 
# Loading: /path/to/json.rb
#=> true

或者尝试(不能使用$ LOAD_PATH回退)来加载和打印特定版本:(有关要求的详细信息,请参阅Gem::Requirement

load_and_print_gem('json','= 2.0.3') 

Example