【问题标题】:Where does require pull ruby files that don't exist on the system?哪里需要提取系统上不存在的 ruby​​ 文件?
【发布时间】:2021-04-01 03:45:17
【问题描述】:

我按照bundler.io 的步骤创建了自己的 gem。

现在我正在调查Rakefile。我明白了:

require "bundler/gem_tasks"

但据我了解,我没有bundler/gem_tasks。那么这是如何工作的呢?该文件预计在哪里? require 如何找到不在其文件夹中的文件?!

它只是指向这个文件:https://github.com/rubygems/bundler/blob/master/lib/bundler/gem_tasks.rb?你能不能像引用单个 ruby​​ 文件一样

require someGem/someRubyfile

ruby docs 不清楚这一点。

我已经查看了this question,还检查了我的$LOAD_PATH。它只包含以下内容:

 "/Library/Ruby/Gems/2.6.0/gems/did_you_mean-1.3.0/lib",
 "/Library/Ruby/Gems/2.6.0/gems/coderay-1.1.3/lib",
 "/Library/Ruby/Gems/2.6.0/gems/method_source-1.0.0/lib",
 "/Library/Ruby/Gems/2.6.0/gems/pry-0.13.1/lib",
 "/Library/Ruby/Site/2.6.0",
 "/Library/Ruby/Site/2.6.0/x86_64-darwin19",
 "/Library/Ruby/Site/2.6.0/universal-darwin19",
 "/Library/Ruby/Site",
 "/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/vendor_ruby/2.6.0",
 "/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/vendor_ruby/2.6.0/x86_64-darwin19",
 "/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/vendor_ruby/2.6.0/universal-darwin19",
 "/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/vendor_ruby",
 "/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0",
 "/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/x86_64-darwin19",
 "/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin19"]

我没有看到提到bundler

我在~/.bundle 中也没有看到任何与gem_tasks 相关的内容。这是否意味着rake build 上的bundler/gem_tasks 将从互联网上下载?

【问题讨论】:

    标签: ruby rubygems rake bundler rakefile


    【解决方案1】:

    Rubygems 用 its own method 覆盖 Ruby 自己的 Kernel#require 方法,该方法按需加载 gem(即将 gem 添加到 $LOAD_PATH,然后需要请求的文件)。

    因此,当您执行 require 'bundler/gem_tasks' 时,rubygems 会在其 require_paths 路径(在每个 gem 的相应 gemspec 中指定)中搜索包含 bundler/gem_tasks.rb 的 gem。如果在您的系统上找到匹配的 gem,它的 require_paths 将添加到 $LOAD_PATH 中,并调用 Ruby 的原始 require 方法,该方法将加载请求的文件。

    无论如何,Ruby 和 Rubygems 都不会从 Internet 动态加载 gem。它只会使用本地安装到配置的 GEM_PATHS 的 gem。您可以通过在命令行上运行 gem env 来找到用于搜索已安装 gem 的配置路径。

    如果使用--disable-gems 命令行参数启动Ruby,它不会自动加载rubygems,因此不会添加Kernel#require 的自定义实现。此处,仅需要您专门添加到 $LOAD_PATH 的位置中的文件。

    【讨论】:

    • 谢谢。 FWIW 我写了一个来自你的答案的答案
    【解决方案2】:

    这评论太大了。它完全从接受的答案中注销:

    我的require_paths 是这样的:spec.require_paths = ["lib"] 所以绝对不存在。所以当我做gem env 时,我得到了以下信息:

    RubyGems Environment:
      - RUBYGEMS VERSION: 3.0.3
      - RUBY VERSION: 2.6.3 (2019-04-16 patchlevel 62) [universal.x86_64-darwin19]
      - INSTALLATION DIRECTORY: /Library/Ruby/Gems/2.6.0
      - USER INSTALLATION DIRECTORY: /Users/honey/.gem/ruby/2.6.0
      - RUBY EXECUTABLE: /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
      - GIT EXECUTABLE: /usr/local/bin/git
      - EXECUTABLE DIRECTORY: /usr/local/bin
      - SPEC CACHE DIRECTORY: /Users/honey/.gem/specs
      - SYSTEM CONFIGURATION DIRECTORY: /Library/Ruby/Site
      - RUBYGEMS PLATFORMS:
        - ruby
        - universal-darwin-19
      - GEM PATHS:
         - /Library/Ruby/Gems/2.6.0
         - /Users/honey/.gem/ruby/2.6.0
         - /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0
      - GEM CONFIGURATION:
         - :update_sources => true
         - :verbose => true
         - :backtrace => false
         - :bulk_threshold => 1000
      - REMOTE SOURCES:
         - https://rubygems.org/
      - SHELL PATH:
         - /Users/honey/google-cloud-sdk/bin
         - /usr/local/bin
         - /usr/bin
         - /bin
         - /usr/sbin
         - /sbin
         - /Library/Apple/usr/bin
    

    所以第一个GEM PATHS 是:/Library/Ruby/Gems/2.6.0。按照我找到的面包屑:/Library/Ruby/Gems/2.6.0/gems/bundler-2.2.2/lib/bundler 在那里我可以找到gem_tasks.rb

    【讨论】:

      猜你喜欢
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 2020-02-27
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      相关资源
      最近更新 更多