require rubygem 如何帮助查找 rubygem 文件? [英] How does require rubygems help find rubygem files?
问题描述
在尝试解决 在 irb 中找到的宝石,而不是在 Ruby 中 ,我尝试查看 require 'rubygems'
对我自己的安装有什么影响:
While trying to solve Gem found in irb, not in Ruby , I tried seeing what effect require 'rubygems'
had on my own installation:
$ 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 安装的库?
If requring rubygems doesn't modify $:
, then how does it help find files? Does it monkeypatch require
? If so, what variable does it use to find rubygem-installed libraries?
推荐答案
这里是当前版本的相关源码:https://github.com/rubygems/rubygems/blob/02ead548e38ff90923444fa7c0ff9f6a5dbd87b0/lib/rubygems/custom_require.rb.(这里是早期版本 (1.5.2)更清楚地表达了发生的事情.)
Here's the current version of the relevant source: https://github.com/rubygems/rubygems/blob/02ead548e38ff90923444fa7c0ff9f6a5dbd87b0/lib/rubygems/custom_require.rb. ( here's an earlier version (1.5.2) that more clearly expresses what happens.)
文档说:
当需要 RubyGems 时,将 Kernel#require
替换为我们自己的能够按需加载宝石.
When RubyGems is required,
Kernel#require
is replaced with our own which is capable of loading gems on demand.
当您调用 require 'x'
时,会发生以下情况:
When you call require 'x'
, this is what happens:
- 如果文件可以从现有的 Ruby 加载路径加载,它是.
- 否则,将搜索已安装的 gem 以查找匹配的文件.如果在 gem 'y' 中找到它,则该 gem 被激活(添加到加载路径).
返回 false 的正常 require
功能 if已经加载的文件被保留.
The normal require
functionality of returning false if
that file has already been loaded is preserved.
它通过打开 module Kernel
并使用 alias gem_original_require require
为原始 require 起别名,然后重新定义 require
以首先调用原始版本,如果不起作用,请查看 gem.
It does this by opening up module Kernel
and aliasing the original require with alias gem_original_require require
, then redefining require
to first call the original version, and look at the gems if that doesn't work.
所以只有在需要 gem 时才会改变加载路径:
So the load path is only changed when you require a 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
这篇关于require rubygem 如何帮助查找 rubygem 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!