154

Ruby 1.9.2 的最新变更集不再使当前目录.成为LOAD_PATH. 我有一个不平凡的 Rakefiles 假设它.是 的一部分LOAD_PATH,所以这破坏了它们(他们报告“没有这样的文件要加载”对于基于项目路径的所有 require 语句)。这样做有什么特别的理由吗?

至于修复,添加$: << "."无处不在的作品,但似乎令人难以置信的hacky,我不想这样做。使我的 Rakefiles 1.9.2+ 兼容的首选方法是什么?

4

7 回答 7

141

这被认为是“安全”风险。

您可以通过使用绝对路径来解决它

File.expand_path(__FILE__) et al

或做

require './filename' (ironically).

或通过使用

require_relative 'filename'

或添加“包含”目录

ruby -I . ...

或相同,使用 irb;

$irb -I .
于 2010-05-24T21:44:30.300 回答
34

有两个原因:

  • 鲁棒性和
  • 安全

两者都基于相同的基本原理:通常,当您的代码运行时,您根本无法知道当前目录是什么。这意味着,当您需要一个文件并依赖它位于当前目录中时,您无法控制该文件是否会存在,或者它是否是您实际希望存在的文件。

于 2010-05-25T07:17:53.543 回答
16

正如其他答案指出的那样,这是一个安全风险,因为.在您的加载路径中是指当前工作目录Dir.pwd,而不是当前正在加载的文件的目录。因此,执行您的脚本的任何人都可以通过cding 到另一个目录来更改它。不好!

我一直在使用构建的完整路径__FILE__作为替代方案。

require File.expand_path(File.join(File.dirname(__FILE__), 'filename'))

与 不同require_relative的是,它向后兼容 Ruby 1.8.7。

于 2011-03-18T06:50:08.517 回答
8

利用require_relative 'file_to_require'

将其放入您的代码中以使 require_relative 在 1.8.7 中工作:

unless Kernel.respond_to?(:require_relative)
  module Kernel
    def require_relative(path)
      require File.join(File.dirname(caller.first), path.to_str)
    end
  end
end
于 2013-01-25T13:50:35.877 回答
6

'。' 在 Unix 世界中,你的路径长期以来一直被认为是一件坏事(例如,参见 http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html)。我认为 Ruby 的人已经被说服不这样做是明智的。

于 2010-05-25T07:32:48.623 回答
3

在我意识到一些事情之前,我发现这是一个令人困惑的变化。

您可以在 .profile (Unix) 中设置 RUBYLIB 并像以前一样继续生活:

export RUBYLIB="."

但如上所述,长期以来一直认为这样做是不安全的。

在绝大多数情况下,您可以通过简单地调用带有前置“.”的 Ruby 脚本来避免问题。例如./scripts/server。

于 2011-04-01T21:45:47.483 回答
3

正如 Jörg W Mittag 指出的那样,我认为你想要使用的是require_relative你需要的文件是相对于require声明的源文件而不是当前的工作目录。

您的依赖项应该与您的 rake 构建文件相关。

于 2011-02-01T11:15:35.657 回答