Почему Ruby 1.9.2 удаляет "." от LOAD_PATH, и какова альтернатива?
Последние изменения в Ruby 1.9.2 больше не делают текущий каталог .
частью вашего LOAD_PATH
. У меня есть нетривиальное число Rakefiles, которые предполагают, что .
является частью LOAD_PATH
, так что это сломало их (они сообщили, что "нет такого файла для загрузки" для всех требующих операторов, основанных на пути к проекту). Было ли какое-то оправдание для этого?
Что касается исправления, то добавление $: << "."
везде работает, но кажется невероятно взломанным, и я не хочу этого делать. Какой предпочтительный способ сделать мой Rakefiles 1.9.2+ совместимым?
Ответы
Ответ 1
Это считалось "угрозой безопасности".
Вы можете обойти это, используя абсолютные пути
File.expand_path(__FILE__) et al
или делать
require './filename' (ironically).
или используя
require_relative 'filename'
если использовать irb
$irb -I .
Ответ 2
Есть две причины:
- надежность и
- Безопасность
Оба основаны на одном и том же базовом принципе: в общем, вы просто не можете знать, что представляет собой текущий каталог, когда ваш код запущен. Это означает, что, когда вам нужен файл и зависит от его наличия в текущем каталоге, у вас нет способа контролировать, будет ли этот файл даже там, или это тот файл, который вы действительно ожидаете там.
Ответ 3
Как указывают другие ответы, это риск безопасности, поскольку .
в вашем пути загрузки относится к текущему рабочему каталогу Dir.pwd
, а не к каталогу текущего загружаемого файла. Поэтому любой, кто выполняет ваш script, может изменить это просто cd
ing в другой каталог. Нехорошо!
В качестве альтернативы я использовал полные пути, построенные из __FILE__
.
require File.expand_path(File.join(File.dirname(__FILE__), 'filename'))
В отличие от require_relative
, это обратно совместимо с Ruby 1.8.7.
Ответ 4
Используйте 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
Ответ 5
'' на вашем пути уже давно считается плохой в мире Unix (см., например, http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html). Я предполагаю, что люди Руби были убеждены в мудрости этого не делать.
Ответ 6
Как отметил Йорг W Миттаг, я думаю, что вы хотите использовать require_relative
, поэтому требуемый файл относится к исходному файлу объявления require
, а не к текущему рабочему директорию.
Ваши зависимости должны быть относительно вашего файла сборки rake.
Ответ 7
Я обнаружил, что это смешение изменений, пока я не понял пару вещей.
Вы можете установить RubyLIB в свой .profile(Unix) и продолжить жизнь, как вы это делали раньше:
export RUBYLIB="."
Но, как упоминалось выше, долгое время считалось небезопасным.
В подавляющем большинстве случаев вы можете избежать проблем, просто называя свои рубиновые скрипты с добавленным ".". например./scripts/server.