【问题标题】: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? 的文档,但到目前为止,我没有看到基于我的搜索的文档链接。

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

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

【问题讨论】:

标签: ruby constants ruby-1.8.7 class-constants


【解决方案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? 不是一个方法。它是一个类似于运算符的关键字。
    猜你喜欢
    • 1970-01-01
    • 2017-01-10
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    相关资源
    最近更新 更多