Ruby中同名的模块和类

Posted

技术标签:

【中文标题】Ruby中同名的模块和类【英文标题】:Module and Class with the same name in Ruby 【发布时间】:2020-07-21 17:30:37 【问题描述】:

比如说,我有 module 'A'module 'B'。在 module B 中,有一个名为 'A' 的类,就像 module 'A'。在这个类中,我想引用 A::ClassC,其中 'A' 是模块,但我收到错误,因为它认为我正在引用类 A,没有ClassC。我可以解决这个问题吗?还是我需要重命名一个? (我想尽可能避免这种情况)

编辑:

这是我当前实现的一个示例,不能作为参考。

    >moduleA
        >classC.rb
    >moduleB
        >classA.rb
        >classB.rb

classA.rb:

module B
    class A < classB

    do something with A::ClassC

    end
end

错误是uninitialized constant ModuleB::ClassA::ClassC

【问题讨论】:

“我遇到了错误”——这些错误会告诉您哪里出了问题、错误发生在哪里以及您是如何到达那里的。如果没有这些错误,就不可能知道发生了什么。请构造一个minimal reproducible example。请注意,所有三个词都很重要:它应该只是一个示例,您不应该发布您的实际代码,而应该创建一个简化的示例来演示问题。它应该是minimal,即不包含任何不需要证明问题的东西。它应该是可重现的,所以如果我复制和粘贴并运行代码,我会看到与您看到的相同的问题。 从你的描述看来,这两个常量好像是在不同的命名空间,所以应该没有问题也没有错误,但是没有错误和代码,就无法判断是怎么回事开。 “我有模块 A 和模块 B ...” – 只显示你的代码而不是描述它。 @JörgWMittag 是的,对不起。错误是uninitialized constant ModuleB::ClassA::ClassC。谢谢。 该错误不可能来自您发布的代码。您的代码中没有ModuleB,您的代码中没有ClassA。一定有其他事情发生,你没有向我们展示。没有它,就不可能弄清楚可能出了什么问题。正如我在之前的评论中所说,根据您的描述,这两个常量听起来像是在不同的命名空间中,所以应该没有问题。 【参考方案1】:

使用范围解析运算符:: 来决定可以从哪个范围类C 中找到。 在您的情况下,您需要一个“主要”范围,因此请使用 :: 运算符作为前缀 - ::A::C

module A
  class C
    def name
      "I am class C from module A"
    end
  end
end

module B
  class A
    def test
      ::A::C.new.name
    end
  end
end

name = B::A.new.test
# => "I am class C from module A"

【讨论】:

以上是关于Ruby中同名的模块和类的主要内容,如果未能解决你的问题,请参考以下文章

Python中模块和类的区别

如何从我自己的同名查找模块中执行CMake的默认查找模块?

要求子目录中的 LuaJIT 模块会覆盖父目录中的同名模块

traceback模块常用函数和类

在python opencv模块中编辑后保存同名图像

解决python开发中模块冲突的具体方法?