Как требуется, чтобы rubygems помог найти файлы rubygem? - PullRequest
9 голосов
/ 31 мая 2011

При попытке решить Gem, найденный в irb, а не в Ruby , я попытался увидеть, какой эффект require 'rubygems' оказал на мою собственную установку:

$ 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?

1 Ответ

13 голосов
/ 31 мая 2011

Вот текущая версия соответствующего источника: https://github.com/rubygems/rubygems/blob/02ead548e38ff90923444fa7c0ff9f6a5dbd87b0/lib/rubygems/custom_require.rb. (Изменить: Вот более ранняя версия (1.5.2) , которая более четко выражает, что происходит.)

Документы говорят:

Когда требуется RubyGems, Kernel#require заменяется нашим собственным, способным загружать самоцветы по требованию.

Когда вы звоните require 'x', эточто происходит:

  • Если файл может быть загружен из существующего пути загрузки Ruby, это так.
  • В противном случае в установленных гемах выполняется поиск файла, который соответствует.Если он найден в gem 'y', этот gem активирован (добавлен в путь загрузки).

Обычная require функция возврата false, если этот файл уже был загружен, сохраняется.

Это делается путем открытия 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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...