如何在 Ruby 中创建私有类常量
Posted
技术标签:
【中文标题】如何在 Ruby 中创建私有类常量【英文标题】:How to I make private class constants in Ruby 【发布时间】:2011-02-21 20:48:33 【问题描述】:在 Ruby 中如何创建私有类常量? (即在课堂内可见但在课堂外不可见)
class Person
SECRET='xxx' # How to make class private??
def show_secret
puts "Secret: #SECRET"
end
end
Person.new.show_secret
puts Person::SECRET # I'd like this to fail
【问题讨论】:
当然,Ruby 中的“私有”并不意味着它在大多数语言中的含义。 Ruby 在隐藏方面并没有那么大,所以如果你想访问某些东西,你总是可以的(但也许不是最明显的语法)。 Ruby 的private
只说它前面不能有一个点 (.
)(我想这也是为什么它不能在 ::
上工作的暗示)
以防万一。 Ruby 1.9.3 现在有了私有常量。
【参考方案1】:
您可以使用@@class_variable 来代替常量,它始终是私有的。
class Person
@@secret='xxx' # How to make class private??
def show_secret
puts "Secret: #@@secret"
end
end
Person.new.show_secret
puts Person::@@secret
# doesn't work
puts Person.class_variable_get(:@@secret)
# This does work, but there's always a way to circumvent privateness in ruby
当然,那么 ruby 不会强制执行 @@secret 的恒定性,但 ruby 一开始就不会强制执行恒定性,所以...
【讨论】:
谢谢...事后看来很明显。【参考方案2】:您还可以将常量更改为类方法:
def self.secret
'xxx'
end
private_class_method :secret
这使得它可以在类的所有实例中访问,但不能在外部访问。
【讨论】:
也许一点元编程会让这更可口。 我想了很久,然后意识到上面的方法不能让实例方法可以使用常量,所以我想我会坚持使用@@var 方法。 @DMisener:如果有人想要元编程魔法,Ruby 有一个丢失常量的方法。 您可以在实例方法中使用self.class.secret
从您的实例中访问此类方法
@brad 实例不能调用私有类方法,即使该实例属于该类。唯一的方法是使用send
,这违背了整个目的。【参考方案3】:
嗯……
@@secret = 'xxx'.freeze
某种作品。
【讨论】:
【参考方案4】:从 ruby 1.9.3 开始,您有 Module#private_constant
方法,这似乎正是您想要的:
class Person
SECRET='xxx'.freeze
private_constant :SECRET
def show_secret
puts "Secret: #SECRET"
end
end
Person.new.show_secret
# => "Secret: xxx"
puts Person::SECRET
# NameError: private constant Person::SECRET referenced
【讨论】:
这真是太棒了。我不知道这甚至是一件事。 直到ruby-doc.org/core-2.0.0/Module.html (ruby-doc.org/core-1.9.3/Module.html) 之前我在Module
API 中看不到这个方法
@KrisRobison 似乎是一些 RDoc 错误。看看 1.9.3 页面末尾的 cmets 部分
@KrisRobison 只是为了确定:这个答案来自 2012 年 8 月,Ruby 2.0 于 2013 年 2 月发布。
谢谢@RenatoZannon。我没有在文档中向下滚动来阅读 cmets。以上是关于如何在 Ruby 中创建私有类常量的主要内容,如果未能解决你的问题,请参考以下文章