在Ruby中,require_relative和require有什么区别?


当前回答

绝对路径

require './app/example_file.rb'

缩短的名字

require_relative 'example_file'

其他回答

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__

上面的答案是正确的,但技术性很强。对于刚接触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中的文件。

我刚刚看到RSpec的代码中有一些关于require_relative是O(1)常数和require是O(N)线性的注释。因此,可能区别在于require_relative比require更可取。

我想补充的是,当使用Windows时,你可以使用require './1。如果脚本在本地或映射的网络驱动器上运行,但如果从UNC \\servername\sharename\文件夹路径运行,则需要使用require_relative './1.rb'。

我不参与其他原因的讨论。

绝对路径

require './app/example_file.rb'

缩短的名字

require_relative 'example_file'