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
答案 0 :(得分:3)
tl;博士: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花费大部分时间做的事情 - 他们管理宝石的负载路径,因此您不必担心它。但是,这对单个文件没有帮助。
此外,require_relative
将从__FILE__
所在的目录中进行搜索,但在IRB中,这是一个非目录(irb)
值!这就是为什么你得到了"无法推断出基本路径"从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__
未被更改,并且可能难以保证。
答案 1 :(得分:0)
加载给定名称,成功时返回true,如果成功则返回false 功能已加载。
如果文件名没有解析为绝对路径,那么它就是 在$ LOAD_PATH($:)。
中列出的目录中搜索如果文件名的扩展名为“.rb”,则将其作为源加载 文件;如果扩展名为“.so”,“。o”或“.dll”,则为默认值 在当前平台上共享库扩展,Ruby加载 共享库作为Ruby扩展。否则,Ruby会尝试添加 “.rb”,“。so”等等,直到找到名称。如果文件名为 无法找到,将引发LoadError。
对于Ruby扩展,给定的文件名可以使用任何共享库 延期。例如,在Linux上,套接字扩展名为“socket.so” 并要求'socket.dll'将加载套接字扩展。
加载文件的绝对路径将添加到$ LOADED_FEATURES ($“)。如果文件的路径已经出现,则不会再次加载文件 $“。例如,要求'a';要求'./a'不会再次加载a.rb。
你的问题的答案是,它根本不适合。
如果您想要相对于文件路径的文件,可以使用require_relative
。
您可以将项目库文件夹添加到$LOAD_PATH
以获取您要求的功能,即require 'my_library'
在IRB中加载本地文件,您可能希望使用load
,因为它使您能够多次加载文件/库,其中require
只会加载文件/库一次。 __FILE__
变量在IRB中工作就像它应该的那样。它是调用变量的文件的标识(在本例中是打开过程)。