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.rb
和 mytest.so
并通过 ruby loader.rb
执行加载器,require_relative
应该工作得很好。
如果您想在 IRB 中运行它,请考虑类似以下内容:
require "#{__dir__}/mytest.so"
这将扩展到当前工作目录,默认情况下应该是您启动它的目录。不过,我建议您不要在脚本中执行此操作,因为它取决于未更改的 __dir__
,这可能很难保证。
关于ruby - 为什么 Ruby 'require' 不允许相对路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31257585/