为什么 Ruby1.9.2要从 LOAD_PATH 中删除“ .”,有什么替代方案吗?

Ruby1.9.2的最新变更集不再使工作目录 .成为你的 LOAD_PATH的一部分。我有不少 Rakefiles 人认为 .LOAD_PATH的一部分,所以这打破了他们(他们报告所有基于项目路径的需求语句“没有这样的文件要加载”)。这样做有什么特别的理由吗?

至于修复,添加 $: << "."到处工作,但似乎令人难以置信的粗糙,我不想这样做。让我的 Rakefile 1.9.2 + 兼容的首选方法是什么?

42612 次浏览

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

您可以使用绝对路径绕过它

File.expand_path(__FILE__) et al

或者在做什么

require './filename' (ironically).

或者使用

require_relative 'filename'

或者添加一个“ include”目录

ruby -I . ...

或相同,使用 irb;

$irb -I .

有两个原因:

  • 稳健性及
  • 保安

两者都基于相同的基本原则: 一般来说,当代码运行时,你根本不知道工作目录是什么。这意味着,当你需要一个文件并且依赖于它在工作目录中时,你没有办法控制这个文件是否会在那里,或者它是否是你实际期望在那里的文件。

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

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

您的依赖项应该相对于您的 rake 构建文件。

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

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

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

require_relative不同,它向后兼容 Ruby1.8.7。

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

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

export RUBYLIB="."

但是正如上面提到的,长期以来这样做被认为是不安全的。

在大多数情况下,你可以通过简单地调用你的 Ruby 脚本来避免问题例如:。/脚本/服务器。

使用 require_relative 'file_to_require'

在1.8.7中,将这些内容加入到代码中,以便让 request _ relant 工作起来:

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