我们可以轻松地从许多着名的仓库(如机架,导轨等)中找到这样的风格.
- PATH_INFO = 'PATH_INFO'.freeze
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
- SCRIPT_NAME = 'SCRIPT_NAME'.freeze
- QUERY_STRING = 'QUERY_STRING'.freeze
- CACHE_CONTROL = 'Cache-Control'.freeze
- CONTENT_LENGTH = 'Content-Length'.freeze
- CONTENT_TYPE = 'Content-Type'.freeze
- HTTP_IF_MODIFIED_SINCE = 'HTTP_IF_MODIFIED_SINCE'.freeze
- HTTP_IF_NONE_MATCH = 'HTTP_IF_NONE_MATCH'.freeze
- HTTP_IF_NONE_MATCH = 'HTTP_IF_NONE_MATCH'.freeze
我不知道为什么这些恒定的字符串被冻结.由于它们都是常量,所以应该只有一个实例.当然,我们可以把“foo”.freeze在某个地方引用相同的单例实例,但是人们通常会写出像HTTP_IF_MODIFIED_SINCEinstead这样的文字变量名.
所以在我看来,尽管使用#freeze也没有任何区别,为什么人们会冻结常量?
解决方法
当您将值重新分配给已初始化的常量时,Ruby至少会写入一个警告:
- > FOO = 'foo'
- > FOO = 'bar'
- # :2: warning: already initialized constant FOO
- # :1: warning: prevIoUs definition of FOO was here
- > FOO
- # => "bar"
但是,在常数中没有改变价值的保护.没有冻结:
- > FOO = 'foo'
- > FOO[1] = '-'
- > FOO
- # => "f-o"
冻结保护常数的值不变.冻结:
- > FOO = 'foo'.freeze
- > FOO[1] = '-'
- # => RuntimeError: can't modify frozen String