Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Why freeze mutable objects assigned to constants?

Consider this offense reported by rubocop

lib/awesomelib/aws.rb:6:10: C: Style/MutableConstant: Freeze mutable objects assigned to constants.
    IP = '34.111.241.111'
     ^^^^^^^^^^^^^^^^

Why should I freeze this IP address?

like image 423
american-ninja-warrior Avatar asked Nov 01 '17 01:11

american-ninja-warrior


People also ask

What is freeze in 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. array. array.

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

How do you freeze a variable in Ruby?

Any object can be frozen by invoking Object#freeze. A frozen object can not be modified: we can't change its instance variables, we can't associate singleton methods with it, and, if it is a class or module, we can't add, delete, or modify its methods.

Are Ruby arrays mutable?

Unlike numbers, booleans, and a few other types, most objects in Ruby are mutable; they are objects of a class that permit changes to the object's state in some way.


2 Answers

You should freeze the value assigned to IP because you've declared IP to be a constant. This indicates that you don't want the value assigned to IP to be mutated.

The problem is that in ruby, assigning a value to a constant does not make the value immutable. You just get a warning if you mutate the value assigned to the constant. To make the value actually immutable, you need to .freeze the value assigned to the constant. After you've frozen a value assigned to a constant, if you try to change the value, you will hit a runtime error.

like image 94
jk_ Avatar answered Sep 19 '22 19:09

jk_


Freezing an object means you are no longer allowed to mutate it. A constant means you are no longer allowed to mutate the binding. (Well, okay, you get a warning if you mutate the binding.) The two just go together well.

In particular, the fact that a mutable object assigned to an immutable binding can still be mutated, might be confusing to some. Just witness the various questions on Stack Overflow about it:

IP = '34.111.241.111'
# Dis is a constant, I can never change it, amirite?

IP << '.255'

IP
#=> '34.111.241.111.255'
# Ooops!

IP.freeze

IP << '.255'
# RuntimeError: can't modify frozen String
like image 24
Jörg W Mittag Avatar answered Sep 17 '22 19:09

Jörg W Mittag