Ruby 源文件名与“require”冲突

发布于 2024-12-23 09:57:05 字数 1338 浏览 3 评论 0原文

处理同名 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: uninitializedconst Geometry::Polygon 这很奇怪,

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

问题问题

是我的应用程序包含一个名为 polygon.rb 的源文件(包含 ActiveRecord 模型)和 ruby-geometry gem 也是如此。因此,当 ruby​​-geometry gem require< /code> 有自己的 polygon.rb它最终会加载我应用程序的 polygon.rb 。据推测,这完全取决于 ruby​​ 搜索目录的顺序。

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

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

What is the correct way to deal with identically named ruby source files and ensuring the correct file is loaded by a given require statement?

Background

I want to make use of the ruby-geometry gem in my Rails 3 app.

I'm attempting to make use of the ruby-geometry Polygon class:

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

However, whenever I attempt to run this code I get the following error:

NameError: uninitialized constant Geometry::Polygon

This is strange because I seem to be able to work with any of the other ruby-geometry classes without a problem (e.g. Geometry::Point, Geometry::Segment).

The Problem

The problem is that my app contains a source file named polygon.rb (contains an ActiveRecord model) and so does the ruby-geometry gem. So when the ruby-geometry gem requires its own polygon.rb it ends up loading my app's polygon.rb instead. Presumably this is all down to the order in which ruby searches through directories.

What is the "proper" approach to resolving this naming clash?

Obviously within code you can use modules to differentiate between namespaces to resolve class name clashes. Is there a simple way to differentiate between identically-named source files when require-ing them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枕花眠 2024-12-30 09:57:05

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

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

对我有用的一种方法是在 GEMFILE 中明确要求此 gem:

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

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

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

但这很难看。

IMHO this is an error in the geometry gem implementation. It is relying in the $LOAD_PATH environment variable to decide where its requested files are. I rather would prefer to use require_relative or using the File.dirname(__FILE__) value to require relative path files in my gems.

For solving your issue you can require the geometry gem before Rails is adding its own paths to the $LOAD_PATH environment variable.

One way to do this that has worked to me is explicitly require this gem in the GEMFILE:

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

Another way would be to remove your app/models path from the $LOAD_PATH array before require the geometry gem:

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

But this is ugly as hell.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文