我们可以轻松地从许多着名的仓库(如机架,导轨等)中找到这样的风格.
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