ChatGPT解决这个技术问题 Extra ChatGPT

Ruby 中的 require_relative 和 require 有什么区别?

Ruby 中的 require_relativerequire 有什么区别?

在 1.9.2 之前不需要 require_relative,因为脚本的当前目录在 $:。请参阅stackoverflow.com/questions/2900370
require_relative 需要一个相对于调用它的文件特别指向的文件。 require 需要包含在 $LOAD_PATH 中的文件。

A
Arslan Ali

看看 docs

require_relative 通过允许您加载与包含 require_relative 语句的文件相关的文件来补充内置方法 require。例如,如果您在“test”目录中有单元测试类,并且在测试“test/data”目录中有它们的数据,那么您可以在测试用例中使用这样的行:require_relative“data/customer_data_1”


require './file.rb'require_relative 'file.rb' 之间有区别吗?
@CiroSantilli 是的。 require_relative 允许您“加载一个相对于包含 require_relative 语句的文件的文件”。使用 require./ 表示相对于您当前工作目录的路径。
我认为更重要的是要注意 require str 将始终搜索 $LOAD_PATH 中的目录。当您需要加载的文件存在于相对于需要加载的文件的某个位置时,您应该使用 require_relative。为“外部”依赖项保留 require
C
Ciro Santilli Путлер Капут 六四事

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 ,这些测试会被评估。

只有 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__

t
the Tin Man

来自 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 找到文档


C
Community

概括

对已安装的 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 路径保持“稳定”,因为它始终以相同的方式相对于需要它的文件。


非常简单的解释!
t
the Tin Man

最佳答案是正确的,但技术性很强。对于那些刚接触 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 中的文件。


我怎样才能对这个答案进行投票并将其一直带到顶部,以便此问题页面的每个访问者都可以立即获得清晰易懂的答案而不会动脑筋?
这个答案最重要的是:)
m
mech

我刚刚看到 RSpec 的代码对 require_relative 是 O(1) 常数和 require 是 O(N) 线性有一些评论。所以可能区别在于 require_relativerequire 更受欢迎。


有趣的。我登陆这里寻找有关速度比较的信息。我的想法是 require_relative 更快,因为加载程序不必遍历加载路径来搜索文件。本质上,require_relative 提供了直接链接。
关于 require_relative speed 和 RSpec changelog 的早期讨论。
t
the Tin Man

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

我不会因为其他原因参与讨论。


我想知道你是如何加载 require_relative 文件的,你能在这个 stackoverflow.com/questions/43487784/… 上提出一个想法吗?
A
Abhishek Tanwar

绝对路径

require './app/example_file.rb'

简称

require_relative 'example_file'

你完全错了。 en.wikipedia.org/wiki/…
这是一个相当糟糕的答案。第一个例子不是绝对路径,发帖人根本懒得解释他的例子。