Ruby require 'file' 和相对路径

19

我正在编写一些rspec测试,但对Ruby的理解不够,让我感到有些尴尬。

我有一个如下所示的文件结构:

  • GUI_Tests/Tests/test_spec.rb
  • GUI_Tests/windows_gui.rb
  • GUI_Tests/upload_tool.rb

当我运行test_spec.rb文件的spec时,需要像这样包含upload_tool文件:

spec -r ../upload_tool -fs test_spec.rb

然后,upload_tool 需要 windows_gui.rb,如下所示:

require '../windows_gui'
我的问题是,为什么我必须相对于test_spec.rb引用windows_gui.rb (使用../)而不是upload_tool.rb?这感觉不对,我想在测试规范之外使用upload_tool.rb,这意味着每次都要更改requires。

显然,我错过了什么,但如果我不相对于测试规范进行引用,我会得到文件未找到错误。

很抱歉我在这里非常无知,但我一无所获。任何想法都很感谢。

BB


2
不要难过 - 我发现处理相对路径是 Ruby 中最烦人的事情之一。我已经在 你希望改进 Ruby 语言的哪些方面 中列出了它。 - Andrew Grimm
2012年8月 - 请注意,此帖子已经两年了。现在大多数人都在使用1.9.2版本。有关最佳解决方案,请参见此帖子https://dev59.com/mmox5IYBdhLWcg3wOx1i(2012年2月)。 - Michael Durrant
1个回答

20

不需要。在您的情况下,require与当前目录相关联,该目录为GUI_Tests/Tests。如果您改为执行以下操作:

cd ..
spec -r upload_tool -fs Test/test_spec.rb

你需要使用这个:

require 'windows_gui' # without '../'

解决这个问题最常见的方法是使用 File.dirname(__FILE__)

require File.join(File.dirname(__FILE__), '..', 'windows_gui')

注意:在 Ruby 1.9.2 中,require 的默认行为已经更改:Ruby: require vs require_relative - 解决在 Ruby <1.9.2 和 >=1.9.2 运行的最佳实践


1
完美 - 就像我说的,我甚至为不得不问而感到尴尬,但我很高兴我这样做了。那很有道理。 - Bobby B
19
实际上,require 并不是相对于当前目录而言,而是相对于搜索路径(即特殊常量 $LOAD_PATH 或它的别名 $:)而言。仅仅是在旧版本的 Ruby 中(即除了还未发布但即将发布的 1.9.2 版本以外的所有版本)默认情况下会将当前目录( . )加入到搜索路径中:p $:.include?('.') # => true 。但是自从 Ruby 1.9.2 版本之后就不再是这样了,因此不能再依赖它。在 Ruby 1.9 中,你可以使用 require_relative ,它是相对于调用它的源文件而言的,而不是相对于搜索路径来工作的。 - Jörg W Mittag
@Jorg:但如果我在1.9中运行这个命令:$:.replace []; require '../somefile',它可以工作。 - Adrian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接