如何在 ruby​​ 中引用子模块的“完整路径”?

Posted

技术标签:

【中文标题】如何在 ruby​​ 中引用子模块的“完整路径”?【英文标题】:How do I refer to a submodule's "full path" in ruby? 【发布时间】:2011-05-26 05:39:15 【问题描述】:

在我的应用中,我有

VeryUniqueModule::Foo
# and…
VeryUniqueModule::Bar

FooBar 分别用于不同的服务。我的应用程序的一部分必须动态确定要引用哪个模块,它可以这样做:

def service_api
  # @relevant_object.service is a string that is either 'Foo' or 'Bar'
  VeryUniqueModule.const_get(@relevant_object.service)
end

稍后会详细介绍。

我刚刚更新了一个库,它现在有自己的*** Foo 类(这本身就是糟糕的设计)。现在,当我尝试调用 @relevant_object.service_api::A_CONSTANT 时,我的应用程序抱怨 库的 Foo 没有 A_CONSTANT

回到上面的service_api -- 我认为const_get 正在返回类本身。事实上我知道它是。如果我在irb 中启动它,一切都如预期的那样——返回值是类本身,我可以调用类上的东西。所以……

    一开始怎么可能存在命名空间冲突?我在service_api 返回的类对象 上寻找A_CONSTANT,而不是在我evaling 的字符串或类似的东西上——不应该有任何命名空间问题,我直接指的是一个对象! 如果这确实是一个问题,我该如何修复 service_api 以使其返回 erm“完整路径”?

【问题讨论】:

你在做什么看起来不错。其他地方可能有错误。 【参考方案1】:

你可以试试这个:

VeryUniqueModule.const_get('::VeryUniqueModule::' + @relevant_object.service)

如果这不起作用,您可以尝试绕过 service_api 并在您需要的任何地方执行此操作 A_CONSTANT

Object.const_get('::VeryUniqueModule::' + @relevant_object.service + '::A_CONSTANT')

注意VeryUniqueModule 之前的::。我认为在这种情况下它不是绝对必要的,但它可能很有用,因为它保证 Ruby 将在全局命名空间中而不是在其他模块中查找 VeryUniqueModule

【讨论】:

这一切都行不通。 const_get 只接受常量名,任何:: 都必须以其他方式处理。例如:class A; B = 42; end; Object.const_get("A::B") # => NameError: wrong constant name A::B

以上是关于如何在 ruby​​ 中引用子模块的“完整路径”?的主要内容,如果未能解决你的问题,请参考以下文章

我有一个需要来自 github 的子模块的 ruby​​ 项目 [关闭]

如何在给定完整路径的情况下导入模块?

给定python 3.5中模块的完整路径,如何导入模块? [复制]

通过引用传递或通过复制传递 - Ruby 模块 [重复]

Ruby中同名的模块和类

在WPF里面如何引用相对路径(非资源)?