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

本文翻译自:What is the difference between require_relative and require in Ruby?

Ruby中的require_relativerequire什么区别?


#1楼

参考:https://stackoom.com/question/FPPG/Ruby中的require-relative和require有什么区别


#2楼

I just saw the RSpec's code has some comment on require_relative being O(1) constant and require being O(N) linear. 我只是看到RSpec的代码对require_relative为O(1)常数和require为O(N)线性有一些评论。 So probably the difference is that require_relative is the preferred one than require . 所以可能的区别是, require_relative是比require首选的一个。


#3楼

require_relative is a convenient subset of require require_relativerequire的便捷子集

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__ ). 当前文件__FILE__ )相关的require_relative './a' require_relative 'a'require_relative './a'

    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 eval ed. 这就是为什么不能在已eval RSpec测试中使用require_relative原因。

The following operations are only possible with require : 以下操作仅可通过require

  • require './a.rb' requires relative to the current directory require './a.rb'相对于当前目录的要求

  • require 'a.rb' uses the search path ( $LOAD_PATH ) to require. require 'a.rb'使用搜索路径( $LOAD_PATH )进行要求。 It does not find files relative to current directory or 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" (ie starts with / or ./ or ../ ), which is always the case for File.expand_path . 这对于require_relative是不可能的,因为文档说仅当“文件名不能解析为绝对路径”(即以/./../开头)时才进行路径搜索,而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. require '/a.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楼

Summary 摘要

Use require for installed gems 已安装宝石的使用require

Use require_relative for local files 对本地文件使用require_relative

require uses your $LOAD_PATH to find the files. require使用$LOAD_PATH查找文件。
require_relative uses the current location of the file using the statement require_relative通过以下语句使用文件的当前位置


require 要求

Require relies on you having installed (eg gem install [package] ) a package somewhere on your system for that functionality. Require依赖于您已在系统中某个位置gem install [package]了某个gem install [package] (例如gem install [package] )以实现该功能。

When using require you can use the " ./ " format for a file in the current directory, eg require "./my_file" but that is not a common or recommended practice and you should use require_relative instead. 使用require可以为当前目录中的文件使用“ ./ ”格式,例如require "./my_file"但这不是常见的或推荐的做法,而应使用require_relative

require_relative require_relative

This simply means include the file 'relative to the location of the file with the require_relative statement'. 这仅意味着将文件“相对于文件的位置并带有require_relative语句”。 I generally recommend that files should be "within" the current directory tree as opposed to "up", eg don't use 通常建议文件应位于当前目录树中,而不要位于“当前目录树”中,例如不要使用

require_relative '../../../filename'

(up 3 directory levels) within the file system because that tends to create unnecessary and brittle dependencies. 文件系统中最多3个目录级别),因为这往往会创建不必要和脆弱的依赖关系。 However in some cases if you are already 'deep' within a directory tree then "up and down" another directory tree branch may be necessary. 但是,在某些情况下,如果您已经“深入”目录树,则可能需要“向上和向下”另一个目录树分支。 More simply perhaps, don't use require_relative for files outside of this repository (assuming you are using git which is largely a de-facto standard at this point, late 2018). 更简单的也许是, 不要对该存储库之外的文件使用require_relative (假设您正在使用git,这在很大程度上是事实上的标准,即2018年底)。

Note that require_relative uses the current directory of the file with the require_relative statement (so not necessarily your current directory that you are using the command from). 请注意, require_relative文件的当前目录与require_relative语句一起使用(因此,不一定要使用命令的当前目录)。 This keeps the require_relative path "stable" as it always be relative to the file requiring it in the same way. 这使require_relative路径始终“稳定”,因为它始终以相同的方式相对于需要它的文件而言。


#5楼

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


#6楼

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语句的文件的文件来补充内置方法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: 例如,如果您在“ test”目录中有单元测试类,而在“ test / data”目录中有它们的数据,那么在测试用例中可以使用如下代码:

 require_relative "data/customer_data_1" 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值