Ruby - 类名中的双冒号(::)

9
我将为您翻译以下内容:

我正在处理一些旧的RoR代码,其中有四个相关的类,每个类都在自己的文件中定义。所有这些类都是解析器类,位于app/models/parsers目录下。每个文件名以_parser.rb结尾。

这里是来自adf_parser.rb文件的示例类定义行:

class Parsers::AdfParser

我对"Parsers::"的作用感到困惑。
  • 我找不到任何明确定义为Parsers的模块。
  • 我没有看到任何关于通过将模块规范添加到类名中隐式创建模块的文档。
  • 唯一的外部依赖是“require 'csv'”。
  • 在类定义中有包含语句,但我认为它们没有任何解释类名的东西。
  • 我创建了一个新的RoR测试项目,并将这些文件的存根放在平行目录中,由于名称错误,它们无法从命令行运行。
  • 我没有看到任何以这种方式命名的类的示例。
我相信这不是什么高深的技术,但我已经浪费了大部分的时间来解决这个问题,如果有人能告诉我发生了什么就太好了。
更新:听起来这只是Rails的一点魔法,基于子目录名称。 我认为我在测试应用程序中遇到错误的原因是我只是通过Ruby解释器运行了文件,而没有以某种方式调用它们与Rails。

这只是一个命名空间。你想要弄清楚什么? - Dave Newton
在命令行中你得到了什么错误?像@DaveNewton说的那样,这只是一个命名空间。如果你想,你可以将它命名为My ::Fancy::Parsers::AdfParser,但是你每次都必须以这种方式访问它。 - awbergs
2
@Dave 是的,但命名空间必须在某个地方定义。我认为 OP 是在说他们找不到“Parsers”模块的定义,所以想知道是否有什么特殊情况。 - mikej
3
我认为Mikej是正确的;如果我理解正确,OP合理地想知道为什么这些类定义不会产生NameError错误,而class Foo::Bar; end在irb中却会产生(至少在1.9.3-p392版本中)。 - gregates
没错 - 我没有看到任何解析器模块的定义。 命名空间和模块有什么不同?它需要某种定义文件吗? - whognu
2个回答

8

class Parsers::AdfParser 实际上等价于:

module Parsers
  class AdfParser

为了使其正常工作且文件能够自动加载,其位置应该是在 parsers/adf_parser.rb,无论是在 app/models 还是 lib 下。基本上,文件路径需要模仿类层次结构。

这就是我所想的,但当我创建了一个新的虚拟项目,并尝试在解析器文件夹下放置类似的类定义时,我遇到了名称错误。这些类文件必须通过Rails创建才能使其工作吗? - whognu
我自己在 lib/ 中尝试过,但没有成功,因此我的答案是错误的(我已经投票删除了)。一旦我尝试使用类似于 app/models/ 中的目录命名空间,它就可以正常工作。很不错。 - BaronVonBraun
1
类不需要通过Rails生成器创建。但是它们需要位于Rails自动加载的路径下,该路径在config/application.rb中设置。通常你会有 config.autoload_paths += Dir["#{config.root}/app/models/**/"] 和同样的lib。然后你可以编写像 Parser.adfParser.new 这样的代码。 - boulder

3

这个文件位于modules的子目录中。按照惯例,Rails会为您进行命名空间。


@user1476065,正如Dave所说,由于您的所有文件都在“parsers”子目录和Rails命名空间中,因此它 - Viren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接