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

时间:2010-09-08 23:05:52

标签: ruby require

Ruby中require_relativerequire有什么区别?

7 个答案:

答案 0 :(得分:286)

只需查看docs

  

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

     

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

require_relative "data/customer_data_1"

答案 1 :(得分:84)

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来获得eval

以下操作仅适用于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__

答案 2 :(得分:74)

来自Ruby API

  

require_relative补充了   内置方法需要允许你   加载相对于的文件   包含require_relative的文件   言。

     

使用require加载文件时   你经常访问   功能正常   安装,并使其可访问   你的系统。要求不提供   加载文件的好方法   项目的代码。这可能很有用   在开发阶段,为   访问测试数据,甚至是   访问“锁定”的文件   在项目内部,不是为了   外用。

     

例如,如果您有单元测试   “test”目录中的类,和   他们在测试中的数据   “test / data”目录,那么你可能会   在测试用例中使用这样的一行:

require_relative "data/customer_data_1" 
     

既然都没有   “测试”和“测试/数据”很可能   在Ruby的库路径中(并且用于   很好的理由),正常的要求不会   找到他们。 require_relative很好   这个特殊问题的解决方案。

     

您可以包含或省略扩展名   (.rb或.so)您所在的文件   负荷。

     

路径必须响应to_str。

您可以在http://extensions.rubyforge.org/rdoc/classes/Kernel.html

找到相关文档

答案 3 :(得分:42)

摘要

使用require安装宝石

require_relative用于本地文件

require使用 $LOAD_PATH 查找文件 require_relative使用语句

使用文件的当前位置

需要

要求依赖于您已在系统上的某个位置安装(例如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路径保持“稳定”,因为它总是以相同的方式相对于需要它的文件。

答案 4 :(得分:23)

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

答案 5 :(得分:14)

我刚刚看到RSpec的代码对require_relative的一些评论是O(1)常量而require是O(N)线性的。所以差异可能是require_relativerequire的首选。

答案 6 :(得分:1)

我想补充一点,当使用Windows时,如果脚本是本地运行的,或者是从映射的网络驱动器运行,则可以使用require './1.rb'但是当从UNC \ servername \ sharename \ folder路径运行时,您需要使用{{ 1}} 我不会因为其他原因而混在讨论中使用。