Why does Ruby 1.9.2 remove “.” from LOAD_PATH, and

2019-01-01 02:54发布

The latest changesets to Ruby 1.9.2 no longer make the current directory . part of your LOAD_PATH. I have a non-trivial number of Rakefiles that assume that . is part of the LOAD_PATH, so this broke them (they reported "no such file to load" for all require statements that based off the project path). Was there a particular justification for doing this?

As for a fix, adding $: << "." everywhere works, but seems incredibly hacky and I don't want to do that. What's the preferred way to make my Rakefiles 1.9.2+ compatible?

7条回答
谁念西风独自凉
2楼-- · 2019-01-01 03:24

It was deemed a "security" risk.

You can get around it by using absolute paths

File.expand_path(__FILE__) et al

or doing

require './filename' (ironically).

or by using

require_relative 'filename'

or adding an "include" directory

ruby -I . ...

or the same, using irb;

$irb -I .
查看更多
宁负流年不负卿
3楼-- · 2019-01-01 03:24

Use require_relative 'file_to_require'

Throw this in your code to make require_relative work in 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
查看更多
笑指拈花
4楼-- · 2019-01-01 03:32

I found this to be a confounding change until I realized a couple of things.

You can set RUBYLIB in your .profile (Unix) and go on with life as you did before:

export RUBYLIB="."

But as mentioned above, it's long been considered unsafe to do so.

For the vast majority of cases you can avoid problems by simply calling your Ruby scripts with a prepended '.' e.g. ./scripts/server.

查看更多
临风纵饮
5楼-- · 2019-01-01 03:41

As others answers point out, it's a security risk because . in your load path refers to the present working directory Dir.pwd, not the directory of the current file being loaded. So whoever is executing your script can change this simply by cding to another directory. Not good!

I've been using full paths constructed from __FILE__ as an alternative.

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

Unlike require_relative, this is backward compatible with Ruby 1.8.7.

查看更多
弹指情弦暗扣
6楼-- · 2019-01-01 03:44

There's two reasons:

  • robustness and
  • security

Both are based on the same underlying principle: in general, you simply cannot know what the current directory is, when your code is run. Which means that, when you require a file and depend on it being in the current directory, you have no way of controlling whether that file will even be there, or whether it is the file that you actually expect to be there.

查看更多
弹指情弦暗扣
7楼-- · 2019-01-01 03:45

As Jörg W Mittag pointed out, I think what you want to be using is require_relative so the file you require is relative to the source file of the require declaration and not the current working dir.

Your dependencies should be relative to your rake build file.

查看更多
登录 后发表回答