Ruby源文件名与`require`冲突

时间:2011-12-30 17:17:19

标签: ruby-on-rails ruby require

处理同名ruby源文件并确保给定require语句加载正确文件的正确方法是什么?

背景

我想在我的Rails 3应用程序中使用ruby-geometry gem。

我正在尝试使用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

这很奇怪,因为我似乎能够毫无问题地使用任何其他ruby-geometry类(例如Geometry::PointGeometry::Segment)。

问题

问题是我的应用程序包含名为polygon.rb(包含ActiveRecord模型)和so does the ruby-geometry gem的源文件。因此,当ruby-geometry gem requires its own polygon.rb最终加载我的应用程序的polygon.rb时。据推测,这完全取决于ruby搜索目录的顺序。

解决此命名冲突的“正确”方法是什么?

显然在代码中,您可以使用模块来区分名称空间以解决类名冲突。是否有一种简单的方法可以在require时区分同名的源文件?

1 个答案:

答案 0 :(得分:1)

恕我直言,这是 geometry gem实现中的错误。它依赖于$LOAD_PATH环境变量来决定其请求的文件的位置。我宁愿使用require_relative或使用File.dirname(__FILE__)值来要求我的宝石中的相对路径文件。

要解决您的问题,您可以在 Rails 添加自己的$LOAD_PATH环境变量路径之前要求几何gem。

对我这样做的一种方法明确要求GEMFILE中的这个宝石:

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

另一种方法是在需要 geometry gem之前从app/models数组中删除$LOAD_PATH路径:

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

但这很丑陋。