【发布时间】:2014-12-19 16:19:44
【问题描述】:
我知道 Ruby 中的“常量”按惯例称为常量,但实际上是可变的。但是,我的印象是,当它们“变异”时会发出警告:
class Z2
M = [0,1]
end
Z2::M # => [0, 1]
Z2::M = [0,3]
(irb):warning: already initialized constant Z2::M
(irb):warning: previous definition of M was here
但我发现并非总是如此:
a = Z2::M
a[1] = 2
Z2::M # => [0,2] and no warning
这是“警告”系统中的一个漏洞吗?我推断一个常量的赋值会重复它,但我猜这也不正确,因为常量和变量似乎指向同一个对象?这是否意味着所有所谓的“常量”都需要被冻结,以防止它们在没有警告的情况下被更改?
【问题讨论】:
-
如果您想防止更改该值,您可以尝试
M = [0,1].freeze。Z2::M[1] = 2=>RuntimeError: can't modify frozen array. -
freeze并非在所有情况下都有效,因为它只会冻结引用,但不会冻结被引用的对象。示例:M=['hello'].freeze; M[0] << '!'- 没有错误,字符串已修改。 -
当然,字符串没有被冻结:)
-
这越来越可怕了。有没有办法确保常量的内容永远不会改变?我认为冻结意味着它没有被改变,但由于一切都是参考,冻结它甚至可能不会阻止参考改变?
-
几乎没有任何东西可以保证在 Ruby 中是不可变的。如果你足够努力,你可以进入任何事情并改变它。 :)
标签: ruby class-constants