检查常量是不是已在 Ruby 类中定义的正确方法

Posted

技术标签:

【中文标题】检查常量是不是已在 Ruby 类中定义的正确方法【英文标题】:Right way to check if a constant is already defined in a Ruby Class检查常量是否已在 Ruby 类中定义的正确方法 【发布时间】:2014-10-25 20:19:20 【问题描述】:

我在我的 Rails 应用程序中实现了某些类作为装饰器,该应用程序位于 Ruby 1.8.7 上。我不断收到警告 - warning: already initialized constant ABC。这里 ABC 是常量的名称。

为了解决这个问题,我正在使用const_defined? 方法,正如answer 中所建议的那样。

我的疑问是 - const_defined? 是检查类常量是否已在 ruby​​ 中定义的正确方法吗?我清楚地看到它可以用来检查模块常量。

我看到defined? 方法也可以像answer 中提到的那样使用。我试图查找 defined? 的文档,但到目前为止,我没有看到基于我的搜索的文档链接。

我不确定在两者中选择哪一个,因为我目前看不出两者之间的明显区别。

能否建议在这种情况下最好使用哪个?为什么?

【问题讨论】:

这可能会有所帮助:***.com/q/3398590/477037 【参考方案1】:

关键字defined? 记录在案here。

最好询问它是否是一个常数,如果它是一个常数很重要,则使用const_defined?。如果你只关心它的定义,那么使用关键字defined?

【讨论】:

感谢您的回答。我正在使用 Ruby 1.8.7 ,如果存在,请您指出特定于该 ruby​​ 版本的文档。使用 const_defined?类中的方法应该不是问题吗?我看到它有效,但我问这个问题的原因是,const_defined?听起来更像是与模块一起使用而不是类,因为它是在'Module' related documentation 下定义的,所以我有一些疑问。你能确认一下吗?谢谢。 @boddhisattva,不要使用 Ruby 1.8.7,它已经过时了。我的意思很糟糕。求求你,使用 Ruby 2.x。 @BorisStitnicky:这些人甚至从哪里获得 ruby​​ 1.8?据我所知,每个主要发行版都已更新。甚至 OSX! @boddhisattva:模块和类基本上是一回事。事实上,Class 继承自 Module,所以每个类都是一个模块。 @BorisStitnicky 我完全支持你:)。但有时,当真正重要的不是你的决定时,你必须忍受它,直到你找到替代方案。鉴于社区已经停止支持这个版本的 Ruby,我完全理解你来自哪里。【参考方案2】:

还有一种选择。这是因为 Ruby 有这个讨厌的 #const_missing 方法,即使在那里也可以意外地提供值,其中 #const_defined? 会指示 false

module M
  def self.const_missing sym; 42 end
end

M.const_defined? "A" #=> false
M::A #=> 42

对于此类情况,您可以使用begin ... rescue ... end 声明:

begin
  M::A; true
rescue NameError
  false
end
#=> true

【讨论】:

【参考方案3】:

由于您使用的是 Ruby 1.8.7,看来您唯一的选择是 const_defined?,因为我找不到来自 defined? 的任何文档

如果您使用的是 Ruby 1.9,我建议您使用定义的?并查看this document 了解更多信息。

【讨论】:

那是因为defined? 不是一个方法。它是一个类似于运算符的关键字。

以上是关于检查常量是不是已在 Ruby 类中定义的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

检查类是不是具有使用 PHPUnit 定义的常量的正确方法

如何检查是不是已在 Ruby 和 Windows 控制台中按下箭头键

有没有办法在 Ruby YAML 文件中指定 ruby​​ 类/模块常量作为值

Ruby入门1

无法将一个类包含到 Ruby 中的另一个类中:未初始化的常量 (NameError)

JAVA常量定义时就要初始化吗?