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

时间:2021-05-12 13:20:07

What is the difference between require_relative and require in Ruby?

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

7 个解决方案

#1


264  

Just look at the docs:

看看医生:

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.

require_relative通过允许您加载相对于包含require_relative语句的文件来补充构建方法所需的功能。

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"

#2


69  

From Ruby API:

从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.

require_relative通过允许您加载相对于包含require_relative语句的文件来补充构建方法所需的功能。

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.

当您使用require加载文件时,您通常是在访问系统中已正确安装并可访问的功能。require并不能很好地解决在项目代码中加载文件的问题。这在开发阶段可能有用,用于访问测试数据,甚至用于访问在项目中“锁定”的文件,而不是用于外部使用。

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.

由于“测试”和“测试/数据”都不可能出现在Ruby的库路径中(而且有充分的理由),正常的需求不会找到它们。对于这个特殊的问题,require_relative是一个很好的解决方案。

You may include or omit the extension (.rb or .so) of the file you are loading.

您可以包含或省略扩展名(。正在加载的文件的rb或.so)。

path must respond to to_str.

路径必须响应to_str。

You can find the documentation at http://extensions.rubyforge.org/rdoc/classes/Kernel.html

您可以在http://extensions.rubyforge.org/rdoc/classes/Kernel.html找到文档

#3


69  

require_relative is a convenient subset of require

require_relative是require的一个方便子集

require_relative('path')

equals:

等于:

require(File.expand_path('path', File.dirname(__FILE__)))

if __FILE__ is defined, or it raises LoadError otherwise.

如果定义了__FILE__,否则会引发LoadError。

This implies that:

这意味着:

  • require_relative 'a' and require_relative './a' require relative to the current file (__FILE__).

    require_relative 'a'和require_relative '。/a'相对于当前文件(__FILE__)的要求。

    This is what you want to use when requiring inside your library, since you don't want the result to depend on the current directory of the caller.

    这是在库中需要使用的,因为您不希望结果依赖于调用者的当前目录。

  • eval('require_relative("a.rb")') raises LoadError because __FILE__ is not defined inside eval.

    eval('require_relative(“a.rb”))会引发LoadError,因为在eval中没有定义__FILE__。

    This is why you can't use require_relative in RSpec tests, which get evaled.

    这就是为什么您不能在被调用的RSpec测试中使用require_relative的原因。

The following operations are only possible with require:

只有在有需要的情况下,才能进行下列操作:

  • require './a.rb' requires relative to the current directory

    需要”。/。rb'需要相对于当前目录

  • require 'a.rb' uses the search path ($LOAD_PATH) to require. It does not find files relative to current directory or path.

    需要的。rb使用需要的搜索路径($LOAD_PATH)。它没有找到相对于当前目录或路径的文件。

    This is not possible with require_relative because the docs say that path search only happens when "the filename does not resolve to an absolute path" (i.e. starts with / or ./ or ../), which is always the case for File.expand_path.

    这对于require_relative来说是不可能的,因为文档说路径搜索只在“文件名不解析为绝对路径”(例如,以/ or ./或../开头)时才会发生,而File.expand_path总是这样。

The following operation is possible with both, but you will want to use require as it is shorter and more efficient:

这两种操作都可以,但是您需要使用require,因为它更短、更有效:

  • require '/a.rb' and require_relative '/a.rb' both require the absolute path.
  • 需要的/。rb和require_relative / a。rb都需要绝对路径。

Reading the source

阅读源代码

When the docs are not clear, I recommend that you take a look at the sources (toggle source in the docs). In some cases, it helps to understand what is going on.

当文档不清楚时,我建议您查看一下源文件(在文档中切换源文件)。在某些情况下,它有助于了解发生了什么。

require:

要求:

VALUE rb_f_require(VALUE obj, VALUE fname) {
  return rb_require_safe(fname, rb_safe_level());
}

require_relative:

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());
}

This allows us to conclude that

这让我们得出结论

require_relative('path')

is the same as:

是一样的:

require(File.expand_path('path', File.dirname(__FILE__)))

because:

因为:

rb_file_absolute_path   =~ File.expand_path
rb_file_dirname1        =~ File.dirname
rb_current_realfilepath =~ __FILE__

#4


25  

require uses the current directory that you are running the program from

require使用正在运行程序的当前目录

require_relative uses the directory of where that program itself resides

require_relative使用程序本身所在的目录

For example, if a program is in ~/code and is called 1.rb and you've done a cd to that directory

例如,如果一个程序在~/代码中,被称为1。rb和你已经做了一个cd到那个目录。

cd ~/code

and you try and run the ruby program with

你试着运行ruby程序

ruby 1.rb

then within 1.rb

然后在1. rb

require './2.rb'
require_relative '3.rb'

both will work.

都工作。

However if you are in another directory, say

但是,如果您在另一个目录中,请说

cd ~/tmp

and you try and run the program with

你试着运行这个程序

ruby ../1.rb

then you will get an error such as

然后你会得到一个错误,例如

/home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- ./2.rb (LoadError)
    from /home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from ../1.rb:1:in `<main>'

when trying to use

当试图使用

require './2.rb'

whereas using

而使用

require_relative '3.rb'

still works ok _because the reference (to 3.rb) is relative to which directory the program (1.rb) is located in.

仍然可以工作,因为引用(到3.rb)相对于程序(1.rb)所在的目录。

#5


13  

The top answers are correct, but deeply technical. For those newer to the Ruby--

上面的答案是正确的,但非常专业。对于Ruby的更新版本—

  • require_relative will most likely be used to bring in code from another file that you wrote.
  • require_relative很可能用于从您编写的另一个文件中引入代码。

for example, what if you have data in ~/my-project/data.rb and you want to include that in ~/my-project/solution.rb? in solution.rb you would add require_relative 'data'.

例如,如果您有~/my-project/data中的数据怎么办?你想把它包含在~/my-project/solution.rb中?在解决方案。您将添加require_relative 'data'。

it is important to note these files do not need to be in the same directory. require_relative '../../folder1/folder2/data' is also valid.

重要的是要注意,这些文件不需要位于同一个目录中。require_relative“. . / . ./ folder1 / folder2 /数据”也是有效的。

  • require will most likely be used to bring in code from a library someone else wrote.
  • 需求很可能被用来从其他人写的库中引入代码。

for example, what if you want to use one of the helper functions provided in the active_support library? you'll need to install the gem with gem install activesupport and then in the file require 'active_support'.

例如,如果您想使用active_support库中提供的助手函数,该怎么办?您将需要使用gem安装activesupport来安装gem,然后在文件中需要“active_support”。

require 'active_support/all'
"FooBar".underscore

Said differently--

说不同,

  • require_relative requires a file specifically pointed to relative to the file that calls it.

    require_relative于调用它的文件,需要一个特定指向的文件。

  • require requires a file included in the $LOAD_PATH.

    require需要包含在$LOAD_PATH中的文件。

#6


11  

I just saw the RSpec's code has some comment on require_relative being O(1) constant and require being O(N) linear. So probably the difference is that require_relative is the preferred one than require.

我刚刚看到RSpec的代码有一些关于require_relative be O(1)的注释,要求是O(N)线性。所以可能不同之处在于require_relative是比require更可取的。

#7


0  

I want to add that when using windows you can use require './1.rb' if the script is run local or from a mapped network drive but when run from an UNC \servername\sharename\folder path you need to use require_relative './1.rb' I don't mingle in the discussion which to use for other reasons.

我想补充的是,在使用windows时,您可以使用require。/1。如果脚本运行在本地或映射的网络驱动器上,但是当从UNC \servername\sharename\文件夹路径运行时,您需要使用require_relative './1。由于其他原因,我不参与讨论。

#1


264  

Just look at the docs:

看看医生:

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.

require_relative通过允许您加载相对于包含require_relative语句的文件来补充构建方法所需的功能。

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"

#2


69  

From Ruby API:

从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.

require_relative通过允许您加载相对于包含require_relative语句的文件来补充构建方法所需的功能。

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.

当您使用require加载文件时,您通常是在访问系统中已正确安装并可访问的功能。require并不能很好地解决在项目代码中加载文件的问题。这在开发阶段可能有用,用于访问测试数据,甚至用于访问在项目中“锁定”的文件,而不是用于外部使用。

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.

由于“测试”和“测试/数据”都不可能出现在Ruby的库路径中(而且有充分的理由),正常的需求不会找到它们。对于这个特殊的问题,require_relative是一个很好的解决方案。

You may include or omit the extension (.rb or .so) of the file you are loading.

您可以包含或省略扩展名(。正在加载的文件的rb或.so)。

path must respond to to_str.

路径必须响应to_str。

You can find the documentation at http://extensions.rubyforge.org/rdoc/classes/Kernel.html

您可以在http://extensions.rubyforge.org/rdoc/classes/Kernel.html找到文档

#3


69  

require_relative is a convenient subset of require

require_relative是require的一个方便子集

require_relative('path')

equals:

等于:

require(File.expand_path('path', File.dirname(__FILE__)))

if __FILE__ is defined, or it raises LoadError otherwise.

如果定义了__FILE__,否则会引发LoadError。

This implies that:

这意味着:

  • require_relative 'a' and require_relative './a' require relative to the current file (__FILE__).

    require_relative 'a'和require_relative '。/a'相对于当前文件(__FILE__)的要求。

    This is what you want to use when requiring inside your library, since you don't want the result to depend on the current directory of the caller.

    这是在库中需要使用的,因为您不希望结果依赖于调用者的当前目录。

  • eval('require_relative("a.rb")') raises LoadError because __FILE__ is not defined inside eval.

    eval('require_relative(“a.rb”))会引发LoadError,因为在eval中没有定义__FILE__。

    This is why you can't use require_relative in RSpec tests, which get evaled.

    这就是为什么您不能在被调用的RSpec测试中使用require_relative的原因。

The following operations are only possible with require:

只有在有需要的情况下,才能进行下列操作:

  • require './a.rb' requires relative to the current directory

    需要”。/。rb'需要相对于当前目录

  • require 'a.rb' uses the search path ($LOAD_PATH) to require. It does not find files relative to current directory or path.

    需要的。rb使用需要的搜索路径($LOAD_PATH)。它没有找到相对于当前目录或路径的文件。

    This is not possible with require_relative because the docs say that path search only happens when "the filename does not resolve to an absolute path" (i.e. starts with / or ./ or ../), which is always the case for File.expand_path.

    这对于require_relative来说是不可能的,因为文档说路径搜索只在“文件名不解析为绝对路径”(例如,以/ or ./或../开头)时才会发生,而File.expand_path总是这样。

The following operation is possible with both, but you will want to use require as it is shorter and more efficient:

这两种操作都可以,但是您需要使用require,因为它更短、更有效:

  • require '/a.rb' and require_relative '/a.rb' both require the absolute path.
  • 需要的/。rb和require_relative / a。rb都需要绝对路径。

Reading the source

阅读源代码

When the docs are not clear, I recommend that you take a look at the sources (toggle source in the docs). In some cases, it helps to understand what is going on.

当文档不清楚时,我建议您查看一下源文件(在文档中切换源文件)。在某些情况下,它有助于了解发生了什么。

require:

要求:

VALUE rb_f_require(VALUE obj, VALUE fname) {
  return rb_require_safe(fname, rb_safe_level());
}

require_relative:

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());
}

This allows us to conclude that

这让我们得出结论

require_relative('path')

is the same as:

是一样的:

require(File.expand_path('path', File.dirname(__FILE__)))

because:

因为:

rb_file_absolute_path   =~ File.expand_path
rb_file_dirname1        =~ File.dirname
rb_current_realfilepath =~ __FILE__

#4


25  

require uses the current directory that you are running the program from

require使用正在运行程序的当前目录

require_relative uses the directory of where that program itself resides

require_relative使用程序本身所在的目录

For example, if a program is in ~/code and is called 1.rb and you've done a cd to that directory

例如,如果一个程序在~/代码中,被称为1。rb和你已经做了一个cd到那个目录。

cd ~/code

and you try and run the ruby program with

你试着运行ruby程序

ruby 1.rb

then within 1.rb

然后在1. rb

require './2.rb'
require_relative '3.rb'

both will work.

都工作。

However if you are in another directory, say

但是,如果您在另一个目录中,请说

cd ~/tmp

and you try and run the program with

你试着运行这个程序

ruby ../1.rb

then you will get an error such as

然后你会得到一个错误,例如

/home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- ./2.rb (LoadError)
    from /home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from ../1.rb:1:in `<main>'

when trying to use

当试图使用

require './2.rb'

whereas using

而使用

require_relative '3.rb'

still works ok _because the reference (to 3.rb) is relative to which directory the program (1.rb) is located in.

仍然可以工作,因为引用(到3.rb)相对于程序(1.rb)所在的目录。

#5


13  

The top answers are correct, but deeply technical. For those newer to the Ruby--

上面的答案是正确的,但非常专业。对于Ruby的更新版本—

  • require_relative will most likely be used to bring in code from another file that you wrote.
  • require_relative很可能用于从您编写的另一个文件中引入代码。

for example, what if you have data in ~/my-project/data.rb and you want to include that in ~/my-project/solution.rb? in solution.rb you would add require_relative 'data'.

例如,如果您有~/my-project/data中的数据怎么办?你想把它包含在~/my-project/solution.rb中?在解决方案。您将添加require_relative 'data'。

it is important to note these files do not need to be in the same directory. require_relative '../../folder1/folder2/data' is also valid.

重要的是要注意,这些文件不需要位于同一个目录中。require_relative“. . / . ./ folder1 / folder2 /数据”也是有效的。

  • require will most likely be used to bring in code from a library someone else wrote.
  • 需求很可能被用来从其他人写的库中引入代码。

for example, what if you want to use one of the helper functions provided in the active_support library? you'll need to install the gem with gem install activesupport and then in the file require 'active_support'.

例如,如果您想使用active_support库中提供的助手函数,该怎么办?您将需要使用gem安装activesupport来安装gem,然后在文件中需要“active_support”。

require 'active_support/all'
"FooBar".underscore

Said differently--

说不同,

  • require_relative requires a file specifically pointed to relative to the file that calls it.

    require_relative于调用它的文件,需要一个特定指向的文件。

  • require requires a file included in the $LOAD_PATH.

    require需要包含在$LOAD_PATH中的文件。

#6


11  

I just saw the RSpec's code has some comment on require_relative being O(1) constant and require being O(N) linear. So probably the difference is that require_relative is the preferred one than require.

我刚刚看到RSpec的代码有一些关于require_relative be O(1)的注释,要求是O(N)线性。所以可能不同之处在于require_relative是比require更可取的。

#7


0  

I want to add that when using windows you can use require './1.rb' if the script is run local or from a mapped network drive but when run from an UNC \servername\sharename\folder path you need to use require_relative './1.rb' I don't mingle in the discussion which to use for other reasons.

我想补充的是,在使用windows时,您可以使用require。/1。如果脚本运行在本地或映射的网络驱动器上,但是当从UNC \servername\sharename\文件夹路径运行时,您需要使用require_relative './1。由于其他原因,我不参与讨论。