在Ruby中,require_relative和require有什么区别?
当前回答
来自Ruby API:
require_relative complements the builtin method require by allowing you to load a file that is relative to the file containing the require_relative statement. When you use require to load a file, you are usually accessing functionality that has been properly installed, and made accessible, in your system. require does not offer a good solution for loading files within the project’s code. This may be useful during a development phase, for accessing test data, or even for accessing files that are "locked" away inside a project, not intended for outside use. For example, if you have unit test classes in the "test" directory, and data for them under the test "test/data" directory, then you might use a line like this in a test case: require_relative "data/customer_data_1" Since neither "test" nor "test/data" are likely to be in Ruby’s library path (and for good reason), a normal require won’t find them. require_relative is a good solution for this particular problem. You may include or omit the extension (.rb or .so) of the file you are loading. path must respond to to_str.
您可以在http://extensions.rubyforge.org/rdoc/classes/Kernel.html上找到相关文档
其他回答
我刚刚看到RSpec的代码中有一些关于require_relative是O(1)常数和require是O(N)线性的注释。因此,可能区别在于require_relative比require更可取。
来自Ruby API:
require_relative complements the builtin method require by allowing you to load a file that is relative to the file containing the require_relative statement. When you use require to load a file, you are usually accessing functionality that has been properly installed, and made accessible, in your system. require does not offer a good solution for loading files within the project’s code. This may be useful during a development phase, for accessing test data, or even for accessing files that are "locked" away inside a project, not intended for outside use. For example, if you have unit test classes in the "test" directory, and data for them under the test "test/data" directory, then you might use a line like this in a test case: require_relative "data/customer_data_1" Since neither "test" nor "test/data" are likely to be in Ruby’s library path (and for good reason), a normal require won’t find them. require_relative is a good solution for this particular problem. You may include or omit the extension (.rb or .so) of the file you are loading. path must respond to to_str.
您可以在http://extensions.rubyforge.org/rdoc/classes/Kernel.html上找到相关文档
上面的答案是正确的,但技术性很强。对于刚接触Ruby的人:
Require_relative很可能用于从您编写的另一个文件引入代码。
例如,如果数据在~/my-project/data中。你想把它包含在~/my-project/solution。Rb ?在解决方案。Rb你会添加require_relative 'data'。
需要注意的是,这些文件不需要在同一个目录中。require_relative“. . / . ./folder1/folder2/data'也是有效的。
Require很可能用于从别人编写的库中引入代码。
例如,如果您想使用active_support库中提供的一个helper函数,该怎么办?你需要用gem install activesupport安装gem,然后在文件中要求'active_support'。
require 'active_support/all'
"FooBar".underscore
说不同,
Require_relative需要一个专门指向调用它的文件的文件。 require要求包含在$LOAD_PATH中的文件。
总结
使用要求安装宝石
对于本地文件使用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路径保持“稳定”,因为它总是相对于以相同方式需要它的文件。
Require_relative是require的一个方便的子集
require_relative('path')
等于:
require(File.expand_path('path', File.dirname(__FILE__)))
如果定义了__FILE__,否则会引发LoadError。
这意味着:
Require_relative 'a'和Require_relative '。/a' require相对于当前文件(__FILE__)。 这是在库内部进行请求时想要使用的,因为您不希望结果依赖于调用者的当前目录。 eval('require_relative(" a.b b")')引发LoadError,因为__FILE__没有在eval中定义。 这就是为什么你不能在RSpec测试中使用require_relative,因为它会被求值。
以下操作只能在require下执行:
需要”。/。Rb '要求相对于当前目录 require ' a.b b'使用搜索路径($LOAD_PATH)来require。它不会查找相对于当前目录或路径的文件。 这在require_relative中是不可能的,因为文档中说路径搜索只发生在“文件名不解析为绝对路径”(即以/或。/或../开头)的情况下,File.expand_path总是这样。
下面的操作都可以使用,但你会想要使用require,因为它更短,更有效:
需要的/。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__
推荐文章
- 如何找到包含匹配值的哈希键
- 如何在Rails中找到当前的路由?
- 在Ruby中->运算符叫什么?
- Rails参数解释?
- Ruby中DateTime和Time的区别
- 如何从代理服务器后面更新Ruby Gems (ISA-NTLM)
- 如何用另一个键替换哈希键
- attr_accessor和attr_accessible的区别
- 如何从Ruby文件路径中获得没有扩展名的文件名
- rvm安装失败:“rvm不是一个函数”
- 学习Ruby on Rails
- Ruby中的数组切片:解释不合逻辑的行为(摘自Rubykoans.com)
- 如何分割一个带分隔符的字符串在Ruby和转换为一个数组?
- 我如何在Ruby中解析YAML文件?
- Rails中的OO设计:在哪里放置东西