web-dev-qa-db-ja.com

なぜRuby 1.9.2はLOAD_PATHから "。"を削除しますが、代替手段は何ですか?

Ruby 1.9.2への最新の変更セットは、現在のディレクトリ.LOAD_PATHの一部にしなくなりました。.LOAD_PATHの一部であるため、これらを壊しました(プロジェクトパスを基にしたすべてのrequireステートメントに対して「ロードするファイルがありません」と報告されました)。

修正に関しては、$: << "."をどこにでも追加することはできますが、信じられないほどハックしているようで、私はそれをしたくありません。 Rakefiles 1.9.2+と互換性を持たせるための推奨される方法は何ですか?

154
John Feminella

「セキュリティ」リスクとみなされました。

絶対パスを使用して回避できます

File.expand_path(__FILE__) et al

またはやって

require './filename' (ironically).

またはを使用して

require_relative 'filename'

または「include」ディレクトリを追加する

Ruby -I . ...

または、irbを使用して;

$irb -I .
140
rogerdpack

2つの理由があります。

  • 堅牢性と
  • 保安

どちらも同じ基本原則に基づいています。一般に、コードを実行すると、現在のディレクトリが何であるかを単純に知ることはできません。つまり、ファイルが必要であり、現在のディレクトリにあることに依存している場合、そのファイルが存在するかどうか、または実際に存在することを期待するファイルであるかどうかを制御する方法がありません。

34
Jörg W Mittag

他の回答が指摘しているように、ロードパスの.は現在ロードされているファイルのディレクトリではなく、現在の作業ディレクトリDir.pwdを参照するため、セキュリティ上のリスクがあります。したがって、スクリプトを実行している人は誰でも、cdingを別のディレクトリに変更するだけでこれを変更できます。良くない!

代わりに__FILE__から構築されたフルパスを使用しています。

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

require_relativeとは異なり、これはRuby 1.8.7と後方互換性があります。

16
Jonathan Tran

つかいます require_relative 'file_to_require'

1.8.7でrequire_relativeが機能するようにコードでこれをスローします。

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
8
Tyler Brock

「。」あなたのパスで長い間、Unixの世界では悪いことと見なされてきました(たとえば、 http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.htmlを参照 )。 Ruby人々はそうしないことの知恵に納得してきたと思います。

6
Rodger

いくつかのことに気付くまで、これは混乱を招く変化であることがわかりました。

.profile(Unix)でRUBYLIBを設定し、以前と同じように作業を続けることができます。

export RUBYLIB="."

しかし、前述のように、そうするのは安全ではないと長い間考えられてきました。

ほとんどの場合、 '<'を前に付けてRubyスクリプトを呼び出すだけで問題を回避できます。例えば./scripts/server。

3
Dylan

JörgW Mittagが指摘したように、使用したいのはrequire_relativeしたがって、必要なファイルは、現在の作業ディレクトリではなく、require宣言のソースファイルに相対的です。

依存関係は、rakeビルドファイルに関連している必要があります。

3
Martin