require ruby​​gem 如何帮助查找 ruby​​gem 文件? [英] How does require rubygems help find rubygem files?

查看:20
本文介绍了require ruby​​gem 如何帮助查找 ruby​​gem 文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试解决 在 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", "."]

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

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 ruby​​gem 如何帮助查找 ruby​​gem 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆