Ruby中require_relative
和require
有什么区别?
答案 0 :(得分:286)
只需查看docs:
require_relative
通过允许您加载与包含require
语句的文件相关的文件来补充内置方法require_relative
。例如,如果您在“test”目录中有单元测试类,并且在测试“test / data”目录下有数据,那么您可以在测试用例中使用这样的行:
require_relative "data/customer_data_1"
答案 1 :(得分:84)
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
来获得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 '../../../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_relative
是require
的首选。
答案 6 :(得分:1)
我想补充一点,当使用Windows时,如果脚本是本地运行的,或者是从映射的网络驱动器运行,则可以使用require './1.rb'
但是当从UNC \ servername \ sharename \ folder路径运行时,您需要使用{{ 1}}
我不会因为其他原因而混在讨论中使用。