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 methodrequire
by allowing you to load a file that is relative to the file containing therequire_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'
andrequire_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")')
raisesLoadError
because__FILE__
is not defined insideeval
.eval('require_relative(“a.rb”))会引发LoadError,因为在eval中没有定义__FILE__。
This is why you can't use
require_relative
in RSpec tests, which geteval
ed.这就是为什么您不能在被调用的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 forFile.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'
andrequire_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 methodrequire
by allowing you to load a file that is relative to the file containing therequire_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'
andrequire_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")')
raisesLoadError
because__FILE__
is not defined insideeval
.eval('require_relative(“a.rb”))会引发LoadError,因为在eval中没有定义__FILE__。
This is why you can't use
require_relative
in RSpec tests, which geteval
ed.这就是为什么您不能在被调用的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 forFile.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'
andrequire_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。由于其他原因,我不参与讨论。