【问题标题】:Refer to method in module with same name as class引用模块中与类同名的方法
【发布时间】:2012-11-11 17:20:12
【问题描述】:

我有一个同名的类和一个模块:

module Pushover
  def configure
    ..
  end
end

module MyModule
  class Pushover
    def blah
      Pushover.configure
    end
  end
end

这不起作用,因为Pushover.configure 调用指向包含类。现在,一个明显的解决方法是重命名该类。但是,模块来自 gem,并且类符合 DSL 中所需的命名约定。所以理想情况下,它们都应该保持不变。我还可以创建第二个助手类并通过它调用,但这一切似乎有点 hacky。我首选的解决方案是直接引用模块方法。

围绕该领域的所有现有问题似乎都在向相反的方向消除歧义 - 即他们想要获得类引用而不是模块。

当我指定Pushover 时,有什么方法可以告诉Ruby 我指的是模块而不是类?

【问题讨论】:

  • 为什么要把模块Pushover和另一个模块中的Pushover类命名为同一个东西?这似乎是您自找麻烦,尤其是从长期来看,如果您必须进行调试或维护。
  • 我同意。然而,我没有太多的选择。我正在使用其他人的 gem 为其他人的应用程序提供补丁。如果我将类名更改为 MyModule::PushoverNotifier,那么使用它的“DSL”会看起来很奇怪。 (这是用于备份 gem btw。)。用户目前可以做notify_by Twitternotify_by Mail。所以notify by Pushover 似乎是一个逻辑扩展,而不是notify_by PushoverNotifier,这将是标准的一个例外。
  • 呃。那是维护代码变得丑陋的时候,当你因为别人的选择而陷入困境时。我感觉到你的痛苦。

标签: ruby


【解决方案1】:

如果你不想查找相对于当前范围的常量,只需使用绝对路径即可:

::Pushover.configure

【讨论】:

  • 啊!因此 :: 有效地将您从当前范围中逃脱。我没有完全理解这一点。谢谢。
  • 它的工作方式与文件系统路径中的/ 完全相同。以/ 开头的路径是绝对路径(或相对于根目录),其他路径是相对路径。在 Ruby 中,常量查找从当前作用域开始,而:: 从“全局作用域”开始(实际上没有全局作用域,它从Object 类开始)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 2014-08-13
  • 2020-02-22
  • 1970-01-01
相关资源
最近更新 更多