319

Rubyrequire_relative和有什么区别?require

4

8 回答 8

316

看看文档

require_relative通过允许您加载与包含该语句require的文件相关的文件来补充内置方法。require_relative

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

require_relative "data/customer_data_1"
于 2010-09-08T23:09:12.237 回答
108

require_relative是一个方便的子集require

require_relative('path')

等于:

require(File.expand_path('path', File.dirname(__FILE__)))

if__FILE__被定义,否则它会引发LoadError

这意味着:

  • require_relative 'a'require_relative './a'要求相对于当前文件( __FILE__)。

    这是您在库中需要时要使用的内容,因为您不希望结果依赖于调用者的当前目录。

  • eval('require_relative("a.rb")')raises LoadErrorbecause __FILE__is not defined inside eval

    这就是为什么您不能require_relative在已编辑的 RSpec 测试中使用的原因eval

以下操作仅适用于require

  • require './a.rb'需要相对于当前目录

  • require 'a.rb'使用搜索路径 ( $LOAD_PATH) 要求。它找不到与当前目录或路径相关的文件。

    这是不可能的,require_relative因为文档说路径搜索仅在“文件名不解析为绝对路径”(即以/or./或开头../)时发生,对于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__
于 2014-10-25T17:58:56.837 回答
77

来自 Ruby API

require_relative 通过允许您加载与包含 require_relative 语句的文件相关的文件来补充内置方法 require。

当您使用 require 加载文件时,您通常会访问系统中已正确安装并可以访问的功能。require 没有提供在项目代码中加载文件的良好解决方案。这在开发阶段可能很有用,用于访问测试数据,甚至用于访问“锁定”在项目内部、不打算供外部使用的文件。

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

require_relative "data/customer_data_1" 

由于“test”和“test/data”都不可能在 Ruby 的库路径中(并且有充分的理由),因此正常的 require 不会找到它们。require_relative 是解决这个特定问题的好方法。

您可以包含或省略正在加载的文件的扩展名(.rb 或 .so)。

path 必须响应 to_str。

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

于 2010-09-08T23:11:47.007 回答
69

概括

用于require已安装的 gem

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

于 2015-04-25T13:06:25.620 回答
38

最佳答案是正确的,但技术性很强。对于那些刚接触 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,gem install activesupport然后在文件中require 'active_support'

require 'active_support/all'
"FooBar".underscore

换个说法——

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

  • require需要包含在$LOAD_PATH.

于 2016-10-06T17:02:30.063 回答
16

require_relative我刚刚看到 RSpec 的代码对O(1) 常数和requireO(N) 线性有一些评论。所以可能区别在于,require_relative它比require.

于 2014-08-04T01:32:55.970 回答
1

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

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

于 2016-02-03T16:41:18.697 回答
-3

绝对路径

require './app/example_file.rb'

简称

require_relative 'example_file'
于 2021-08-18T05:38:13.183 回答