为什么Ruby 1.9.2从LOAD_PATH中删除“。”,还有什么替代方案?

问题描述 投票:154回答:7

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

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

ruby rake require load-path
7个回答
140
投票

这被视为“安全”风险。

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

File.expand_path(__FILE__) et al

或做

require './filename' (ironically).

或者通过使用

require_relative 'filename'

或添加“包含”目录

ruby -I . ...

或者相同,使用irb;

$irb -I .

34
投票

有两个原因:

  • 稳健性和
  • 安全

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


16
投票

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

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

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

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


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

6
投票

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


3
投票

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

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

export RUBYLIB="."

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

对于绝大多数情况,只需使用前缀“。”调用Ruby脚本,就可以避免出现问题。例如./scripts/server。


3
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.