Ruby 中的 require_relative
和 require
有什么区别?
$:
。请参阅stackoverflow.com/questions/2900370
看看 docs:
require_relative 通过允许您加载与包含 require_relative 语句的文件相关的文件来补充内置方法 require。例如,如果您在“test”目录中有单元测试类,并且在测试“test/data”目录中有它们的数据,那么您可以在测试用例中使用这样的行:require_relative“data/customer_data_1”
require_relative
是 require
的一个方便子集
require_relative('path')
等于:
require(File.expand_path('path', File.dirname(__FILE__)))
如果定义了 __FILE__
,否则引发 LoadError
。
这意味着:
require_relative 'a' 和 require_relative './a' 要求相对于当前文件 (__FILE__)。这是您在库中需要时要使用的内容,因为您不希望结果依赖于调用者的当前目录。
eval('require_relative("a.rb")') 引发 LoadError 因为 __FILE__ 没有在 eval 中定义。这就是为什么你不能在 RSpec 测试中使用 require_relative ,这些测试会被评估。
只有 require
才能进行以下操作:
require './a.rb' 需要相对于当前目录
require 'a.rb' 使用搜索路径 ($LOAD_PATH) 来要求。它找不到与当前目录或路径相关的文件。这对于 require_relative 是不可能的,因为文档说路径搜索仅在“文件名不解析为绝对路径”(即以 / 或 ./ 或 ../ 开头)时发生,File.expand_path 总是如此.
两者都可以进行以下操作,但您将希望使用 require
,因为它更短且更高效:
require '/a.rb' 和 require_relative '/a.rb' 都需要绝对路径。
阅读源码
当文档不清楚时,我建议您查看源(在文档中切换源)。在某些情况下,它有助于了解正在发生的事情。
要求:
VALUE rb_f_require(VALUE obj, VALUE fname) {
return rb_require_safe(fname, rb_safe_level());
}
要求相对:
VALUE rb_f_require_relative(VALUE obj, VALUE fname) {
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
rb_loaderror("cannot infer basepath");
}
base = rb_file_dirname(base);
return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}
这使我们可以得出结论
require_relative('path')
是相同的:
require(File.expand_path('path', File.dirname(__FILE__)))
因为:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
来自 Ruby API:
require_relative 通过允许您加载与包含 require_relative 语句的文件相关的文件来补充内置方法 require。当您使用 require 加载文件时,您通常会访问系统中已正确安装并可以访问的功能。 require 没有提供在项目代码中加载文件的良好解决方案。这在开发阶段可能很有用,用于访问测试数据,甚至用于访问“锁定”在项目内部、不打算供外部使用的文件。例如,如果您在“test”目录中有单元测试类,并且在测试“test/data”目录下有它们的数据,那么您可以在测试用例中使用这样的行: require_relative "data/customer_data_1" “测试”和“测试/数据”都不太可能在 Ruby 的库路径中(并且有充分的理由),正常的需求不会找到它们。 require_relative 是解决这个特定问题的好方法。您可以包含或省略正在加载的文件的扩展名(.rb 或 .so)。 path 必须响应 to_str。
您可以在 http://extensions.rubyforge.org/rdoc/classes/Kernel.html 找到文档
概括
对已安装的 gem 使用 require
对本地文件使用 require_relative
require
使用您的 $LOAD_PATH
来查找文件。
require_relative
使用该语句使用文件的当前位置
要求
Require 依赖于您已在系统某处安装(例如 gem install [package]
)用于该功能的软件包。
使用 require
时,您可以对当前目录中的文件使用“./
”格式,例如 require "./my_file"
,但这不是常见或推荐的做法,您应该使用 require_relative
反而。
require_relative
这仅仅意味着包含文件'相对于文件位置的 require_relative 语句'。我通常建议文件应该在当前目录树“内”而不是“向上”,例如不要使用
require_relative '../../../filename'
(最多 3 个目录级别)在文件系统中,因为这往往会创建不必要的和脆弱的依赖关系。但是,在某些情况下,如果您已经“深入”在目录树中,则可能需要“上下”另一个目录树分支。也许更简单地说,不要对这个存储库之外的文件使用 require_relative (假设您使用的是 git,这在 2018 年末这一点很大程度上是事实上的标准)。
请注意,require_relative
将文件的当前目录 与 require_relative 语句一起使用(因此不一定是您使用命令的当前目录)。这使 require_relative
路径保持“稳定”,因为它始终以相同的方式相对于需要它的文件。
最佳答案是正确的,但技术性很强。对于那些刚接触 Ruby 的人:
require_relative 很可能用于从您编写的另一个文件中引入代码。
例如,如果您在 ~/my-project/data.rb
中有数据并且想要将其包含在 ~/my-project/solution.rb
中怎么办?在 solution.rb
中,您将添加 require_relative 'data'
。
重要的是要注意这些文件不需要位于同一目录中。 require_relative '../../folder1/folder2/data'
也是有效的。
require 很可能用于从其他人编写的库中引入代码。
例如,如果您想使用 active_support
库中提供的帮助函数之一怎么办?您需要使用 gem install activesupport
安装 gem,然后在文件 require 'active_support'
中安装。
require 'active_support/all'
"FooBar".underscore
换个说法——
require_relative 需要一个相对于调用它的文件特别指向的文件。
require 需要包含在 $LOAD_PATH 中的文件。
我刚刚看到 RSpec 的代码对 require_relative
是 O(1) 常数和 require
是 O(N) 线性有一些评论。所以可能区别在于 require_relative
比 require
更受欢迎。
require_relative
更快,因为加载程序不必遍历加载路径来搜索文件。本质上,require_relative
提供了直接链接。
我想补充一点,在使用 Windows 时,如果脚本在本地运行或从映射的网络驱动器运行,则可以使用 require './1.rb'
,但从 UNC \\servername\sharename\folder
路径运行时,您需要使用 require_relative './1.rb'
。
我不会因为其他原因参与讨论。
require_relative
文件的,你能在这个 stackoverflow.com/questions/43487784/… 上提出一个想法吗?
绝对路径
require './app/example_file.rb'
简称
require_relative 'example_file'
不定期副业成功案例分享
require './file.rb'
和require_relative 'file.rb'
之间有区别吗?require_relative
允许您“加载一个相对于包含require_relative
语句的文件的文件”。使用require
,./
表示相对于您当前工作目录的路径。require str
将始终搜索 $LOAD_PATH 中的目录。当您需要加载的文件存在于相对于需要加载的文件的某个位置时,您应该使用require_relative
。为“外部”依赖项保留require
。