如何在ruby类中锁定类变量


class Test
def self.states
@@states ||= OpenStruct.new({initial: 'initial', started: 'started'}).freeze
end
end
  1. 以上代码是否意味着@@states被冻结
  2. 那么@@states可重新分配吗
  3. 在类方法中编写@states@@states是否相同
  4. 如果@@states不被冻结或不可重新分配,那么一旦@@states被设置为不可重新指定,我如何锁定它

以上代码是否意味着@@states被冻结?

是(有点(。您对对象调用了.freeze,因此对象被冻结。即技术上;冷冻的";事物是变量引用的对象,而不是变量本身:

[1] pry(main)> x = "hello".freeze
=> "hello"
[2] pry(main)> x.frozen?
=> true
[3] pry(main)> x = "world"
=> "world"
[4] pry(main)> x.frozen?
=> false

@@states可重新分配吗?

没有"公共接口";更改变量,但您可以通过元编程来完成:

Test.class_variable_set('@@states', 'CHANGED!')

在类方法中写入@states@@states相同吗?

否。类中的实例变量和类变量之间有细微的区别例如,请参阅此答案以获得更详细的解释。

如果@@states不被冻结或不可重新分配,那么一旦它被设置为不可重新指定,我如何锁定@@状态?

您不能让无法更改/重新分配ruby中的任何内容;你能做的最好的事情就是让它变得非常尴尬——也就是说,你必须写一些";"黑客";改变它。

换句话说,您可以删除任何";公共接口";并使对象冻结(这正是你已经做过的(,但是,由于ruby是一种具有强大元编程的动态语言,如果你真的下定决心,总有一些后门方法可以更改变量。例如,请参见此库。

这并不是ruby独有的——例如,在C/C++中,可以通过使用指针来更改常量

最新更新