ruby - 为什么 Ruby 'require' 不允许相对路径?

标签 ruby

This SO post通过声称 require 只会搜索相对于脚本运行的路径来回答这个问题。但这确实看起来是真的。我会详细说明。

我创建了一个快速的 C 扩展并将其编译为 mytest.so。然后,在同一目录中,我启动了 irb

irb(main):009:0> require 'mytest.so'
LoadError: cannot load such file -- mytest.so

这是预料之中的,因为另一个答案中的声明是 require 正在搜索相对于 irb 运行的位置。在我的例子中是 /usr/bin/irb。所以我尝试了另一个问题的 required_relative 解决方案:

irb(main):006:0> require_relative './mytest.so'
LoadError: cannot infer basepath

运气不好。仅供引用 - mytest.so 在这里完成制表符,因此 irb 清楚地知道它在当前工作目录中。此外,我可以很容易地证明这一点:

irb(main):004:0> system("pwd")
/home/mike/Documents/ruby_test
# => true
irb(main):005:0> File.expand_path("./")
# => "/home/mike/Documents/ruby_test"

好的最终测试,我将假设 irb 正在 /usr/bin 中执行 尽管有证据表明这一点。

irb(main):011:0> require '../../home/mike/Documents/ruby_test/mytest.so'
LoadError: cannot load such file -- ../../home/mike/Documents/ruby_test/mytest.so

如果有人能阐明 require 的情况,我将不胜感激?

顺便说一句,我知道我可以通过提供确切的文件路径来解决这个问题。这个问题是关于尝试了解表面之下发生的事情。

require '/home/mike/Documents/ruby_test/mytest.so' # this works

最佳答案

tl;dr:IRB 很特殊,有一些奇怪的规则。 Ruby 通常可以很好地处理相对路径。

require 将搜索加载路径(您可以通过检查 $:$LOAD_PATH 来查看)。这将不包括您从中启动 IRB 的目录:

> $:
 => ["/usr/local/rvm/rubies/jruby-head/lib/ruby/2.2/site_ruby", "/usr/local/rvm/rubies/jruby-head/lib/ruby/stdlib"]

所以那里没有乐趣,除非您明确地将您的目录添加到加载路径。这就是 Rubygems 和 Bundler 花费大部分时间做的事情——它们管理 gems 的加载路径,所以你不必担心它。但是,这对单个文件没有帮助。

此外,require_relative 将从__FILE__ 所在的目录中搜索,但在IRB 中,这是一个非目录(irb)值(value)!这就是为什么在从 IRB 尝试 require_relative 时会出现“无法推断基本路径”的问题;由于当前正在执行的文件 __FILE__ 不是正确的路径,require_relative 无法弄清楚从哪里开始。

当您不从 IRB 运行时,这不是真正的问题; require_relative 'mytest.so' 在脚本中执行时应该可以正常工作,因为当前正在执行的脚本将填充 __FILE__。也就是说,如果你有 loader.rbmytest.so 并通过 ruby loader.rb 执行加载器,require_relative 应该工作得很好。

如果您想在 IRB 中运行它,请考虑类似以下内容:

require "#{__dir__}/mytest.so"

这将扩展到当前工作目录,默认情况下应该是您启动它的目录。不过,我建议您不要在脚本中执行此操作,因为它取决于未更改的 __dir__,这可能很难保证。

关于ruby - 为什么 Ruby 'require' 不允许相对路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31257585/

相关文章:

ruby-on-rails - 通过 HTTP、Ruby(无 ROR)序列化/反序列化对象

ruby - 使用 "debugger"gem 在 Emacs 中调试 Ruby 1.9

ruby - 与 DataMapper 和 Sinatra 建立关联

ruby - 通过数组键对哈希数组排序

ruby-on-rails - 解析 youtube 网址

css - 如何使用 link_to 帮助程序(ruby on rails)将字形图标添加到下拉菜单链接

ruby - 在方法定义中将等号 ('=' ) 放在方法名称之后有什么作用?

ruby-on-rails - 如何创建和管理用户?

ruby - 为什么 ruby​​-prof 将 "Kernel#` 列为资源占用者?

mysql - 任何不在本地安装mysql服务器的安装mysql2 GEM的方法