Ruby 受保护的常量,或类似的实现

Ruby protected constants, or similar implementation

我想执行以下操作:

module A
  class B
  end
  # can call A:B within module
end

# cannot call A:B outside of module (like private constant)

我基本上想要私有常量,但我希望能够在模块内使用命名空间调用它们。

在我看来,我需要对 A 中的 B 常量进行某种受保护的行为,但据我所知,Ruby 没有受保护的常量。

我很想听听有关如何实施的想法。

这可以做到,但我不知道你为什么要这样做。

module A
  class B
    def greeting
      puts "hi within #{self}"
    end
  end
  puts "constants within A = #{constants}"
  B.new.greeting
  # <more code>
  # lastly...
  const_set(:B, nil)
end

显示:

constants within A = [:B]
hi within #<A::B:0x00005b2a18ffc538>
warning: already initialized constant A::B
warning: previous definition of B was here

然后,

A::B.new.greeting
  NoMethodError (undefined method `new' for nil:NilClass)

如果需要,您可以在命令行中添加 '-W'-W0 以禁止显示警告消息。

我知道 ActiveSupport 有一种方法 Object::remove_constant 允许将 const_set(:B, nil)(或 const_set("B", nil))替换为:

Object.public_send(:remove_const, :B)

这可能更可取。