在Ruby中,require_relative和require有什么区别?

在Ruby中require_relativerequire之间有什么区别?

184768 次浏览

只要看看文档:

require_relative是内置方法require的补充,它允许你加载一个相对于包含require_relative语句的文件的文件。

例如,如果你在"test"目录下有单元测试类,在"test/data"目录下有它们的数据,那么你可以在测试用例中使用这样的行:

require_relative "data/customer_data_1"

来自Ruby API:

require_relative补充 内置方法,允许你 控件的相关文件 包含require_relative的文件 声明。< / p >

当你使用require加载文件时, 你通常会访问 功能是正确的 安装,并使其易于访问 您的系统。要求不提供 加载文件的好解决方案 项目代码。这可能很有用 在开发阶段,为 访问测试数据,甚至为 访问被“锁”起来的文件 在项目内部,不是用于 外使用。< / p >

例如,如果你有单元测试 “test”目录中的类,以及 测试下的数据 "test/data"目录,那么你可能 在测试用例中使用如下一行:

require_relative "data/customer_data_1"
无论是以来< p > "test"和"test/data"都可能是 在Ruby的库路径中(对于 好理由),正常的要求不会 找到他们。Require_relative是个好方法

.

. 你可以包括或省略扩展名 (.Rb或。so)的文件 装载。< / p >

Path必须响应to_str。

你可以在http://extensions.rubyforge.org/rdoc/classes/Kernel.html找到文档

我刚刚看到RSpec的代码有一些关于require_relative是O(1)常数和require是O(N)线性的注释。因此,可能区别在于require_relativerequire更受欢迎。

require_relativerequire的一个方便的子集

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,它会被evaled。< / p >

以下操作仅适用于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());
}

require_relative:

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__

总结

对已安装的宝石使用require

对本地文件使用require_relative

require使用你的$LOAD_PATH来查找文件。
require_relative使用语句

来使用文件的当前位置

需要

Require依赖于你已经在你的系统的某个地方安装了一个包(例如gem install [package])来实现该功能。

当使用require时,你可以使用"例如require "./my_file",但这不是一个常见的或建议的做法,你应该使用require_relative代替。

require_relative

这仅仅意味着包含“相对于require_relative语句的文件位置”的文件。我一般建议文件应该是“;within”;当前目录树,而不是"up",例如使用

require_relative '../../../filename'

(最多3个目录级别),因为这会产生不必要的、脆弱的依赖关系。然而,在某些情况下,如果你已经在目录树中“深”,那么“向上和向下”;可能需要另一个目录树分支。也许更简单地说,不要对这个存储库之外的文件使用require_relative(假设你使用的是git,在2018年底,这在很大程度上是一个事实上的标准)。

注意,require_relative使用当前目录文件的require_relative语句(所以不一定是你正在使用命令的当前目录)。这将保持require_relative路径“稳定”。因为它总是相对于文件需要它以同样的方式。

我想补充的是,当使用Windows时,如果脚本在本地或从映射的网络驱动器运行,则可以使用require './1.rb',但当从UNC \\servername\sharename\folder路径运行时,则需要使用require_relative './1.rb'

我不参与其他原因的讨论。

上面的答案是正确的,但技术性很强。对于刚接触Ruby的人:

  • require_relative最有可能用于从您编写的另一个文件引入代码。

例如,如果你在~/my-project/data.rb中有数据,而你想将其包含在~/my-project/solution.rb中,该怎么办?在solution.rb中添加require_relative 'data'

需要注意的是,这些文件不需要在同一个目录中。require_relative '../../folder1/folder2/data'也是有效的。

  • require最有可能用于从其他人编写的库中引入代码。

例如,如果你想使用active_support库中提供的一个helper函数,该怎么办?你需要用gem install activesupport安装gem,然后在文件require 'active_support'中安装。

require 'active_support/all'
"FooBar".underscore

说不同,

  • require_relative需要一个相对于调用它的文件专门指向的文件。

  • require需要包含在$LOAD_PATH. xml文件中的文件。

绝对路径

require './app/example_file.rb'

缩短的名字

require_relative 'example_file'