Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are there frozen constants everywhere?

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_SINCEinstead.

So in my opinion, it doesn't make any difference in spite of using #freeze, so why do people freeze constants?

like image 701
Weihang Jian Avatar asked Dec 30 '14 09:12

Weihang Jian


People also ask

What is frozen string?

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.

What is the use of freeze rails?

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]".

What does .freeze do Ruby?

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 are constants in Ruby?

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.


1 Answers

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 
like image 99
spickermann Avatar answered Sep 25 '22 02:09

spickermann