处理同名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::Point
,Geometry::Segment
)。
问题是我的应用程序包含名为polygon.rb
(包含ActiveRecord模型)和so does the ruby-geometry gem的源文件。因此,当ruby-geometry gem require
s its own polygon.rb
最终加载我的应用程序的polygon.rb
时。据推测,这完全取决于ruby搜索目录的顺序。
解决此命名冲突的“正确”方法是什么?
显然在代码中,您可以使用模块来区分名称空间以解决类名冲突。是否有一种简单的方法可以在require
时区分同名的源文件?
答案 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)
但这很丑陋。