【问题标题】:Iterate over only public Ruby constants仅迭代公共 Ruby 常量
【发布时间】:2016-08-28 23:36:18
【问题描述】:

从 Ruby 2.0 左右开始,可以使用 private_constant 将常量设为私有,如果直接在声明模块之外使用该常量,则会导致错误。

但是,constantsconst_defined? 仍然返回私有常量,const_get 允许访问它们。有没有办法以编程方式识别私有常量并在运行时过滤掉它们?

(注意:What does Module.private_constant do? Is there a way to list only private constants? 及其答案并未专门针对这种情况,而是相反(如何仅列出 private 常量)。)


更新:看起来好像在 Ruby 1.9 和 2.0 中,constants 确实只包含公共常量。从 2.1 开始,无参数 constants 仍然只包含公共常量,但使用 constants(false)inherit 设置为 false(即,仅列出此模块中定义的常量,而不是其祖先模块中定义的常量)有优势暴露私有常量的效果。

【问题讨论】:

  • 它们仍然被定义。你想让鲁比撒谎吗?
  • 我没有在 Ruby 2.1.4 中复制您的问题:2.1.4 :001 > module Foo; X = 1; Y = 2; private_constant :Y; end; Foo.constants 返回[:X]
  • @tadman 不,我只是在记录我尝试过的内容。
  • @NeilSlater 这很有趣。当我尝试将其减少到最小的测试用例时,我也没有看到它。

标签: ruby private-members


【解决方案1】:

您可以通过以下方式识别常量:

class A
  C = "value"
  private_constant :C
  C2 = "value2"
end

A.constants #public constants
#=> [:C2]
A.constants(false) #public & private constants
#=> [:C, :C2]
A.constants(false) - A.constants #private constants
#=> [:C]

【讨论】:

  • OP 似乎想要非私有常量数组,并表示constants 方法返回 all 常量(他们想要过滤掉私有常量)。但是,我同意,这是可行的,并且 A.constants 也按预期返回 [:C2] - 以及 OP 似乎想要的 - 所以不完全确定 OP 的实际问题是什么。
  • @NeilSlater,我回答了Is there a way to programmatically identify private constants?
  • 新编辑显示所有可能的方式。无法反驳 :-) 我想知道为什么问题说这对 OP 不起作用?
  • @NeilSlater 我在我认为有问题的代码中传递了(false)inherit= 与公共/私人有任何关系并不明显,所以我认为这不是问题。
猜你喜欢
  • 1970-01-01
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 2016-10-25
  • 2011-05-13
  • 2012-02-14
  • 1970-01-01
相关资源
最近更新 更多