2011-12-30 16 views
3

同じ名前のrubyソースファイルを扱う正しい方法と、適切なファイルが指定されたrequire文でロードされるようにするにはどうすればよいですか?Rubyのソースファイル名と `require`との衝突

背景

私は私のRails 3アプリケーションで ruby-geometry宝石を利用したい

私はルビージオメトリPolygonクラスを利用するようにしようとしています:

require 'geometry' # the main ruby-geometry gem file 

module SomeModule 
    def SomeMethod(vertices) 
     polygon = Geometry::Polygon.new(vertices) 

     # Do some stuff with polygon... 
    end 
end 

私はこのコードを実行しようとするたびしかし、私は次のエラーを取得:

NameError: uninitialized constant Geometry::Polygon

を問題なく他のルビジオメトリクラス(例えばGeometry::PointGeometry::Segment)を使って作業できるように思われるので、これは奇妙です。

問題

問題は、私のアプリは、ソースpolygon.rbという名前のファイル(ActiveRecordのモデルが含まれている)とso does the ruby-geometry gemが含まれていることです。だから、ルビージオメトリの宝石requires its own polygon.rbは、代わりに私のアプリのpolygon.rbの読み込みを終了します。おそらく、これはすべて、ルビがディレクトリを検索する順番です。

この名前の衝突を解決するための「適切な」アプローチとは何ですか?

明らかにのコードでは、モジュールを使用して名前空間を区別してクラス名の衝突を解決できます。 requireを実行すると、同じ名前のソースファイルを簡単に区別することはできますか?

+0

コードファイルの名前を変更できませんか?なぜこれはオプションではないのですか?それはそれを行う最も簡単な方法でしょう。それを 'polygon_record.rb'などの名前に変更してください。 – Linuxios

+1

これはオプションですが、これを行うのは 'require'メカニズムが壊れていることを認めているようです。ソースファイルに名前を付けることができるはずですが、私のアプリケーションが依存するn個の宝石の中のソースファイルと名前が衝突しないようにする必要はありません。さらに、2つの宝石(私は簡単に名前を変更できません)のソースファイルの間に衝突がある場合はどうなりますか?私はもっ​​と良い解決策がないとは信じられません。 – tomtheguvnor

+0

本当にモデルの名前を変更したくない場合は絶対に絶対パスでファイルを要求することができますが、私はそれをお勧めしません。 –

答えて

1

IMHOこれはジオメトリ gemの実装でのエラーです。要求されたファイルがどこにあるかは、$LOAD_PATH環境変数に依存しています。私はむしろrequire_relativeを使用するか、File.dirname(__FILE__)の値を使用して私の宝石に相対パスファイルを要求することを好みます。

Railsの$LOAD_PATH環境変数に、独自のパスを追加する前に、あなたはジオメトリ宝石を 必要とすることができ、あなたの問題を解決するため

。私に働いている、これを行うに

一つの方法は、明示的GEMFILEにこの宝石を必要としている:

gem "ruby-geometry", :require => "geometry" 

ジオメトリ宝石を必要とする前にもう一つの方法は$LOAD_PATH配列からごapp/modelsパスを削除することです:

old_load_path = $LOAD_PATH 
$LOAD_PATH.delete(File.expand_path("#{Rails.root}/app/models")) 
require "geometry" 
$LOAD_PATH.replace(old_load_path) 

しかし、これは地獄のように醜いです。

+0

ありがとうございます。あなたのGemfileのハックがトリックでした。 gemの修正を作成し、プルリクエストを送信する方法について説明します。 – tomtheguvnor