We can easily find such style from lots of famous repositories, like rack, rails, etc.
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
I wonder why these constant strings are frozen. Since they are all constants, there should be only one instance. Of course we can put "foo".freeze
somewhere to reference the same singleton instance, however people usually write literal variable name like HTTP_IF_MODIFIED_SINCE
instead.
So in my opinion, it doesn't make any difference in spite of using #freeze
, so why do people freeze constants?
It is correct that Ruby prints a warning when you re-assign a value to an already initialized constant:
> FOO = 'foo'
> FOO = 'bar'
# :2: warning: already initialized constant FOO
# :1: warning: previous definition of FOO was here
> FOO
# => "bar"
But there is no protection from changing the value in the constant. Example without freeze
:
> FOO = 'foo'
> FOO[1] = '-'
> FOO
# => "f-o"
But freeze
allows to protect the value of the constants from being changed. Example with freeze
:
> FOO = 'foo'.freeze
> FOO[1] = '-'
# => RuntimeError: can't modify frozen String