设置一个Ruby变量,永远不能再改变它?

时间:2015-02-24 17:23:49

标签: ruby

给出一个Java示例:

class MyClass {
  private final int variable;

  MyClass(int variable) {
    this.variable = variable;
  }

}

我能用Ruby做final吗?我查了freeze,但我不确定它是否是正确的方法。在创建我的类的新实例时,我不需要分配变量,我需要在其中一个方法中设置它,一旦它设置了我想要冻结它。

3 个答案:

答案 0 :(得分:2)

他们被称为constants。 Ruby中的常量由UPPER_CASE名称定义。

VARIABLE = "foo"

值得一提的是,从技术上讲,在Ruby中无法阻止变量被更改。实际上,如果您尝试将值重新分配给常量,您将收到警告,而不是错误。

➜  ~  irb
2.1.5 :001 > VARIABLE = "foo"
 => "foo"
2.1.5 :002 > VARIABLE = "bar"
(irb):2: warning: already initialized constant VARIABLE
(irb):1: warning: previous definition of VARIABLE was here
 => "bar"

还值得注意的是,如果您尝试替换常量的值,则使用常量将警告您,但如果您更改常量值则不会。

2.1.5 :001 > VARIABLE = "foo"
 => "foo"
2.1.5 :002 > VARIABLE.upcase!
 => "FOO"
2.1.5 :003 > VARIABLE
 => "FOO"

为了防止更改常量引用的值,可以在分配后冻结该值。

2.1.5 :001 > VARIABLE = "foo".freeze
 => "foo"
2.1.5 :002 > VARIABLE.upcase!
RuntimeError: can't modify frozen String
    from (irb):2:in `upcase!'
    from (irb):2
    from /Users/weppos/.rvm/rubies/ruby-2.1.5/bin/irb:11:in `<main>'
2.1.5 :003 > VARIABLE
 => "foo"

这是一个班级内的一个例子。

class MyClass
  MY_CONSTANT = "foo"
end

MyClass::MY_CONSTANT
# => "foo"

答案 1 :(得分:2)

您的代码的Ruby等价物如下所示:

class MyClass
  def initialize(variable)
    @variable = variable.freeze
  end
end

一般来说,这是不赞成的,因为这个方法没有对象variable所代表的所有权,所以当他们的对象突然被冻结时,调用者可能会有一个粗鲁的惊喜。

请注意,这可以防止操纵@variable对象,但不会阻止重复分配给该属性。没有任何东西可以阻止这种行为。

如果适用,您可以随时复制并冻结。

在一般的练习中,你通常不会这样做,而是采取严格的方法,不操纵你的课程没有的对象,或者如果你需要做出改变的话,复制它们。

因此,总而言之,在Ruby中没有像这样锁定事物的传统,并且在语言中对这种行为的支持很少。

答案 2 :(得分:0)

最接近的可能是常数。 Ruby常量就像一个变量,除了它的值应该在程序的持续时间内保持不变。 Ruby解释器实际上并不强制执行常量的常量,但如果程序更改常量的值,它会发出警告。