【问题标题】:Ruby protected constants, or similar implementationRuby 保护的常量,或类似的实现
【发布时间】:2020-05-07 21:02:37
【问题描述】:

我想实现以下内容:

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 没有保护常量。

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

【问题讨论】:

  • @SebastianPalma 将 B 指定为私有常量,并且不允许使用其命名空间 A::B 调用该常量。私有常量只能称为B
  • 你是对的......
  • “不能”是什么意思?唯一真正不能在其范围之外被访问的是局部变量。元编程方法让您可以访问 Ruby 中的私有内容。

标签: ruby-on-rails ruby oop private


【解决方案1】:

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

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)

这可能更可取。

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    相关资源
    最近更新 更多