Почему Ruby 1.9.2 удаляет "." из LOAD_PATH, а какая альтернатива? - PullRequest
154 голосов
/ 25 мая 2010

Последние изменения в Ruby 1.9.2 больше не делают текущий каталог . частью вашего LOAD_PATH. У меня есть нетривиальное количество файлов Rake, которые предполагают, что . является частью LOAD_PATH, так что это сломало их (они сообщили, что «такой файл не загружается» для всех операторов require, основанных на пути проекта). Было ли какое-то конкретное оправдание для этого?

Что касается исправления, добавление $: << "." везде работает, но кажется невероятно хакерским, и я не хочу этого делать. Какой предпочтительный способ сделать мой Rakefiles 1.9.2+ совместимым?

Ответы [ 7 ]

140 голосов
/ 25 мая 2010

Это считалось риском "безопасности".

Вы можете обойти это, используя абсолютные пути

File.expand_path(__FILE__) et al

или делает

require './filename' (ironically).

или с помощью

require_relative 'filename'

или добавление каталога «include»

ruby -I . ...

или то же самое, используя irb;

$irb -I .
34 голосов
/ 25 мая 2010

Есть две причины:

  • прочность и
  • безопасность

Оба основаны на одном и том же базовом принципе: в общем, вы просто не можете знать, что является текущим каталогом, когда ваш код выполняется. Это означает, что когда вам требуется файл, и вы зависите от того, находится ли он в текущем каталоге, у вас нет возможности контролировать, будет ли этот файл вообще там или это тот файл, который вы действительно ожидаете там.

16 голосов
/ 18 марта 2011

Как указывают другие ответы, это угроза безопасности, поскольку . в вашем пути загрузки относится к текущему рабочему каталогу Dir.pwd, а не к каталогу текущего загружаемого файла. Так что, кто бы ни выполнял ваш скрипт, он может изменить это просто, cd, перейдя в другой каталог. Не хорошо!

В качестве альтернативы я использовал полные пути, построенные из __FILE__.

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

В отличие от require_relative, он обратно совместим с Ruby 1.8.7.

8 голосов
/ 25 января 2013

Использование 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 голосов
/ 25 мая 2010

'' на вашем пути уже давно считается плохой вещью в мире Unix (см., например, http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html). Я предполагаю, что ребята из Ruby были убеждены в мудрости этого не делать.

3 голосов
/ 02 апреля 2011

Я находил это смущающим изменением, пока не понял пару вещей.

Вы можете установить RUBYLIB в свой .profile (Unix) и продолжать жить, как делали раньше:

export RUBYLIB="."

Но, как уже упоминалось выше, это долгое время считалось небезопасным.

В подавляющем большинстве случаев вы можете избежать проблем, просто вызывая свои скрипты на Ruby с префиксом '.' например ./scripts/server.

3 голосов
/ 01 февраля 2011

Как отметил Jörg W Mittag, я думаю, вы хотите использовать require_relative, поэтому требуемый файл относится к исходному файлу объявления require, а не к текущему рабочему каталогу.

Ваши зависимости должны быть относительно вашего файла сборки рейка.

...