Rubyrequire_relative
和有什么区别?require
8 回答
看看文档:
require_relative
通过允许您加载与包含该语句require
的文件相关的文件来补充内置方法。require_relative
例如,如果您在“test”目录中有单元测试类,并且在测试“test/data”目录下有它们的数据,那么您可以在测试用例中使用这样的行:
require_relative "data/customer_data_1"
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")')
raisesLoadError
because__FILE__
is not defined insideeval
。这就是为什么您不能
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__
来自 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找到文档
概括
用于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
路径保持“稳定”,因为它始终以相同的方式相对于需要它的文件。
最佳答案是正确的,但技术性很强。对于那些刚接触 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
.
require_relative
我刚刚看到 RSpec 的代码对O(1) 常数和require
O(N) 线性有一些评论。所以可能区别在于,require_relative
它比require
.
我想补充一点,在使用 Windows 时,require './1.rb'
如果脚本在本地运行或从映射的网络驱动器运行,则可以使用,但从 UNC\\servername\sharename\folder
路径运行时,您需要使用require_relative './1.rb'
.
我不会因为其他原因参与讨论。
绝对路径
require './app/example_file.rb'
简称
require_relative 'example_file'