We can easily find such style from lots of famous repositories, like rack, rails, etc.
For example in rack:
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
Another examle in rails:
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?
By freezing string literals, your program will raise an exception when trying to modify the string literal. Example: Without magic comment, you can modify the string literals. name = 'Johny' name << ' Cash' puts name #=> Johny Cash. With magic comment, an exception will be raised when you modify string literals.
By using #freeze, I'm able to create a constant that's actually constant. This time, when I attempt to modify the string, I get a RuntimeError. Here' a real-world example of this in the ActionDispatch codebase. Rails hides sensitive data in logs by replacing it with the text "[FILTERED]".
The freeze method in Ruby is used to ensure that an object cannot be modified. This method is a great way to create immutable objects. Any attempt to modify an object that has called the freeze method will result in the program throwing a runtime error.
What is a constant in Ruby? A constant is a type of variable which always starts with a capital letter. They can only be defined outside of methods, unless you use metaprogramming. Constants are used for values that aren't supposed to change, but Ruby doesn't prevent you from changing them.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With